ASP.NET错误处理

 

两种方式:
一、返回错误信息和错误码,这样客户端可以把错误信息直接显示给用户,省去了解析错误码的烦恼。
服务器端实现:
下面的类解析错误码定义文件,并且把错误信息加入hastTable
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Web;
using System.Web.Caching;
using System.Collections;

namespace MeetingProxy.MeetingException
{
    /** <summary>
    /// 错误码的描述
    /// </summary>
    public class ErrProcedure
    {

        private static Hashtable errMessages = new Hashtable();
        public static Hashtable GetErrMessages()
        {
            if (CommonCache.Get("ErrMessage") as Hashtable == null)
            {
                string path = null;

                HttpContext context = HttpContext.Current;
                if (context != null)
                    path = context.Server.MapPath("~ErrMessage.xml");
                else
                    path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ErrMessage.xml");

                XmlDocument xdoc = new XmlDocument();
                xdoc.Load(path);
                foreach (XmlNode child in xdoc.LastChild)
                {
                    errMessages.Add(int.Parse(child.LastChild.InnerText), child.FirstChild.InnerText);
                }
                CacheDependency cd = new CacheDependency(path);
                CommonCache.Max("ErrMessage", errMessages,cd);
                return errMessages;

            }
            else
            {
                return CommonCache.Get("ErrMessage") as Hashtable;
            }
        }

 

    }
}
错误码文件:
<?xml version="1.0" encoding="UTF-8"?>
<ErrMessage>
  <Err>
    <Description>登录会议室错误</Description>
    <ErrCode>100</ErrCode>
  </Err>
  <Err>
    <Description>您申请的会议室被别人抢用,会议室创建失败,请重新申请</Description>
    <ErrCode>101</ErrCode>
  </Err>
   <Err>
    <Description>必须有端口号</Description>
    <ErrCode>200</ErrCode>
  </Err>
 
  <Err>
    <Description>用户名或者密码错误</Description>
    <ErrCode>300</ErrCode>
  </Err>
</ErrMessage>

异常定义:
using System;
using System.Collections.Generic;
using System.Text;

namespace MeetingProxy
{
    public class MeetingBaseException:ApplicationException
    {
        int errCode;
        public MeetingBaseException(string message, int errCode)
            : base(message)
        {
            this.errCode = errCode;
        }
        public MeetingBaseException(int errCode)
        {
            this.errCode = errCode;
 
        }
        public int ErrCode
        {
            get { return errCode; }
            set { this.errCode = value; }
        }
    }
}

异常抛出方式:
private string VerifySession()
        {
            string passport = null;
            if (HttpContext.Current != null)
            {

                    passport = HttpContext.Current.Session["Username"] as string;
           
            }
            if (passport == null)
            {
                //用户没有通过Session验证
                throw new MeetingBaseException(ErrProcedure.GetErrMessages()[301].ToString(), 301);
            }
           
            return passport;
        }客户端:
客户端如果检测到是MeetingBaseException就可以直接把错误信息显示给客户,而不用解析错误码。
缺点:虽然省去了错误码的解析,但是如果有多语言化问题,错误信息直接显示就不行了。
如果客户端想只显示某些错误信息给客户,这种方式也不方便。
二、只返回错误码,客户端去解析错误码,这样提供了,最大的灵活性。
实现:服务器省去了错误码的解析。
异常抛出方式: throw new MeetingBaseException(108);客户端实现:
下面是用到资源文件的例子,如果只有一种资源,就可以用ErrProcedure处理。
因为全局资源被编译为资源类,而错误码是数字,不能做标志符,因此把他做简单处理,正数前加“R”,负数加“R_”,修改后类似(简体资源): <data name="R303" xml:space="preserve">
    <value>用户名已经存在</value>
  </data>
<data name="R_500" xml:space="preserve">
    <value>系统异常</value>
  </data>处理方式:
public static string  GetErrInfo(int errCode)
    {
        string resourceKey;
        if (errCode >= 0)
        {
            resourceKey = "R" + errCode.ToString();
        }
        else
        {
            errCode = errCode * -1;
            resourceKey = "R_" + errCode.ToString();
        }
        
        Type t = typeof(Resources.Login);
        PropertyInfo pi = t.GetProperty(resourceKey);
        return pi.GetValue(null, null).ToString();
     

    }
此处用反射简化了很多,见http://www.cnblogs.com/bluewater/archive/2006/09/08/498660.html
我认为第二种方式在大多数情况下都比较好,如果是很小的项目,第一种方式会简单些。
webservice异常处理:
在webservice中抛出异常,让客户端去解析是很困难的,因为客户端可能是js,php等,对ws的封装很差。因此我认为好一些的异常处理应该这样:
返回结果分两种类型,一种是只包含简单的错误码:
using System;
using System.Collections.Generic;
using System.Text;

namespace YahooBase.Result
{
    /** <summary>
    /// 普通返回值
    /// </summary>
    public  class SoapResult
    {
        private int errCode;
        public SoapResult()
        { }
        public SoapResult(int errCode)
        {
            this.errCode = errCode;
        }
        public int ErrCode
        {
            get
            { return errCode; }
            set { errCode = value; }
        }
    }
}
web服务方法实现:
[WebMethod()]
public SoapResult FreeConfrence()
    {
        try
        {
            mc.FreeConfrence();
            return new SoapResult(0);
        }
        catch (MeetingBaseException me)
        {
            return new SoapResult(me.ErrCode);

        }
        catch (ApplicationException ae)
        {
            Log4net.log.Error(ae);
            return new SoapResult(-500);
        }

        catch (Exception e)
        {
            if (e.InnerException != null)
            {
                Log4net.log.Error(e.InnerException);
            }
            Log4net.log.Error(e);
            return new SoapResult(-500);
        }
 
    }另一种返回复杂结果:
先定义返回值类型如,HistoryFeeResult
using System;
using System.Collections.Generic;
using System.Text;

namespace YahooBase.Result
{
    /** <summary>
    /// 查询历史帐单信息
    /// </summary>
    public class HistoryFeeResult:SoapResult
    {
        public HistoryFeeResult(int errCode):base(errCode)
        {}
        public HistoryFeeResult()
        {}
       public MonthFee[] MonthFeeList;
    }
    public class MonthFee
    {
       public string MonthName;
       public Category[] CategoryList;

    }
    public class Category
    {
        public Category(decimal fee, string name)
        {
            Fee = fee;
            Name = name;
        }
        public Category()
        { }
 
       public decimal Fee;
       public string Name;

    }
}
web方法实现:
实现方式和第一种一样,只是如果有自定义异常,则调用HistoryFeeResult的只有错误码的构造函数。
如果调用成功会返回(Post方式):
  <?xml version="1.0" encoding="utf-8" ?>
- <HistoryFeeResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
  <ErrCode>0</ErrCode>
- <MonthFeeList>
- <MonthFee>
  <MonthName>三月</MonthName>
- <CategoryList>
- <Category>
  <Fee>44.6</Fee>
  <Name>市话</Name>
  </Category>
- <Category>
  <Fee>46.6</Fee>
  <Name>长途</Name>
  </Category>
  </CategoryList>
  </MonthFee>
  </MonthFeeList>
  </HistoryFeeResult>出错会返回(Post方式):
  <?xml version="1.0" encoding="utf-8" ?>
 <HistoryFeeResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
  <ErrCode>105</ErrCode>
  </HistoryFeeResult>   这样客户端就可以从解析服务器端异常的繁重工作中解脱出来,也易于和非.net程序的交互。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值