错误处理

两种方式:
一、返回错误信息和错误码,这样客户端可以把错误信息直接显示给用户,省去了解析错误码的烦恼。
服务器端实现:
下面的类解析错误码定义文件,并且把错误信息加入hastTable
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
using  System.Xml.Serialization;
None.gif
using  System.IO;
None.gif
using  System.Xml;
None.gif
using  System.Web;
None.gif
using  System.Web.Caching;
None.gif
using  System.Collections;
None.gif
None.gif
namespace  MeetingProxy.MeetingException
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 错误码的描述
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class ErrProcedure
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif        
private static Hashtable errMessages = new Hashtable();
InBlock.gif        
public static Hashtable GetErrMessages()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (CommonCache.Get("ErrMessage"as Hashtable == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
string path = null;
InBlock.gif
InBlock.gif                HttpContext context 
= HttpContext.Current;
InBlock.gif                
if (context != null)
InBlock.gif                    path 
= context.Server.MapPath("~ErrMessage.xml");
InBlock.gif                
else
InBlock.gif                    path 
= Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ErrMessage.xml");
InBlock.gif
InBlock.gif                XmlDocument xdoc 
= new XmlDocument();
InBlock.gif                xdoc.Load(path);
InBlock.gif                
foreach (XmlNode child in xdoc.LastChild)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    errMessages.Add(
int.Parse(child.LastChild.InnerText), child.FirstChild.InnerText);
ExpandedSubBlockEnd.gif                }

InBlock.gif                CacheDependency cd 
= new CacheDependency(path);
InBlock.gif                CommonCache.Max(
"ErrMessage", errMessages,cd);
InBlock.gif                
return errMessages;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return CommonCache.Get("ErrMessage"as Hashtable;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif
InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
错误码文件:
None.gif <? xml version = " 1.0 "  encoding = " UTF-8 " ?>
None.gif
< ErrMessage >
None.gif  
< Err >
None.gif    
< Description > 登录会议室错误 </ Description >
None.gif    
< ErrCode > 100 </ ErrCode >
None.gif  
</ Err >
None.gif  
< Err >
None.gif    
< Description > 您申请的会议室被别人抢用,会议室创建失败,请重新申请 </ Description >
None.gif    
< ErrCode > 101 </ ErrCode >
None.gif  
</ Err >
None.gif   
< Err >
None.gif    
< Description > 必须有端口号 </ Description >
None.gif    
< ErrCode > 200 </ ErrCode >
None.gif  
</ Err >
None.gif  
None.gif  
< Err >
None.gif    
< Description > 用户名或者密码错误 </ Description >
None.gif    
< ErrCode > 300 </ ErrCode >
None.gif  
</ Err >
None.gif </ ErrMessage >
None.gif
None.gif
异常定义:
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
None.gif
namespace  MeetingProxy
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class MeetingBaseException:ApplicationException
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
int errCode;
InBlock.gif        
public MeetingBaseException(string message, int errCode)
InBlock.gif            : 
base(message)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.errCode = errCode;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public MeetingBaseException(int errCode)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.errCode = errCode;
InBlock.gif 
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public int ErrCode
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn errCode; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gifthis.errCode = value; }
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

异常抛出方式:
None.gif private   string  VerifySession()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
string passport = null;
InBlock.gif            
if (HttpContext.Current != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif
InBlock.gif                    passport = HttpContext.Current.Session["Username"as string;
ExpandedSubBlockEnd.gif            

ExpandedSubBlockEnd.gif            }

InBlock.gif            
if (passport == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//用户没有通过Session验证
InBlock.gif
                throw new MeetingBaseException(ErrProcedure.GetErrMessages()[301].ToString(), 301);
ExpandedSubBlockEnd.gif            }

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

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            errCode 
= errCode * -1;
InBlock.gif            resourceKey 
= "R_" + errCode.ToString();
ExpandedSubBlockEnd.gif        }

InBlock.gif         
InBlock.gif        Type t 
= typeof(Resources.Login);
InBlock.gif        PropertyInfo pi 
= t.GetProperty(resourceKey);
InBlock.gif        
return pi.GetValue(nullnull).ToString();
InBlock.gif      
InBlock.gif
ExpandedBlockEnd.gif    }

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

InBlock.gif    public  class SoapResult
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private int errCode;
InBlock.gif        
public SoapResult()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{ }
InBlock.gif        
public SoapResult(int errCode)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.errCode = errCode; 
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public int ErrCode
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gifreturn errCode; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ errCode = value; }
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
web服务方法实现:
[WebMethod()] None.gif
public  SoapResult FreeConfrence()
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
try
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            mc.FreeConfrence();
InBlock.gif            
return new SoapResult(0);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
catch (MeetingBaseException me)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return new SoapResult(me.ErrCode);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif        
catch (ApplicationException ae)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Log4net.log.Error(ae);
InBlock.gif            
return new SoapResult(-500);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (e.InnerException != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Log4net.log.Error(e.InnerException);
ExpandedSubBlockEnd.gif            }

InBlock.gif            Log4net.log.Error(e);
InBlock.gif            
return new SoapResult(-500);
ExpandedSubBlockEnd.gif        }

InBlock.gif 
ExpandedBlockEnd.gif    }
另一种返回复杂结果:
先定义返回值类型如,HistoryFeeResult
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
None.gif
namespace  YahooBase.Result
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 查询历史帐单信息
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class HistoryFeeResult:SoapResult
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public HistoryFeeResult(int errCode):base(errCode)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{}
InBlock.gif        
public HistoryFeeResult()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{}
InBlock.gif       
public MonthFee[] MonthFeeList;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
public class MonthFee
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif       
public string MonthName;
InBlock.gif       
public Category[] CategoryList;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif    
public class Category
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public Category(decimal fee, string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Fee 
= fee;
InBlock.gif            Name 
= name;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public Category()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{ }
InBlock.gif 
InBlock.gif       
public decimal Fee;
InBlock.gif       
public string Name;
InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值