当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > 错误处理

ASP.NET
Asp.net 时间操作基类(支持短日期,长日期,时间差)
asp.net 获取机器硬件信息(cpu频率、磁盘可用空间、内存容量等)
asp.net 数据库备份还原(sqlserver+access)
Asp.Net 数据操作类(附通用数据基类)
Asp.net 弹出对话框基类(输出alet警告框)
Asp.net 文件上传类(取得文件后缀名,保存文件,加入文字水印)
Asp.net Socket客户端(远程发送和接收数据)
Asp.net 字符串操作基类(安全,替换,分解等)
Asp.Net数据输出到EXCEL表格中
asp.net Gridview里添加汇总行
asp.net UpdatePanel的简单用法
asp.net ajaxControlToolkit FilteredTextBoxExtender的简单用法
this connector is disabled错误的解决方法
sql事务应用积累
asp.net Page.Controls对象(找到所有服务器控件)
在asp.NET中字符串替换的五种方法
ASP.NET缓存方法分析和实践示例代码
asp.net 在DNN模块开发中遇到的resx怪问题
ASP.NET State service状态服务的问题解决方法
asp.net 结合mysql存储过程进行分页代码

ASP.NET 中的 错误处理


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-23   浏览: 105 ::
收藏到网摘: n/a

两种方式:
一、返回错误信息和错误码,这样客户端可以把错误信息直接显示给用户,省去了解析错误码的烦恼。
服务器端实现:
下面的类解析错误码定义文件,并且把错误信息加入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(nullnull).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>