首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WCF异常处理#2

WCF异常处理#2
EN

Stack Overflow用户
提问于 2012-01-03 16:24:08
回答 2查看 1.5K关注 0票数 3

我有N个WCF的服务方式。我想实现异常处理。我的服务将由.net和非.net客户端使用。故障契约是实现异常处理的唯一途径吗?如果是,那么如何避免实现服务中的所有方法。如何在一个地方实现异常处理,以处理服务中所有方法的异常。友好的提供一些代码,以便于在稳定下。

这是我的代码样本。

MyFaultContract

代码语言:javascript
复制
[DataContract()]  
public class FleetCustomException  
{  
    [DataMember()]  
    public string Title;  
    [DataMember()]  
    public string ExceptionMessage;  
    [DataMember()]  
    public string InnerException;  
    [DataMember()]  
    public string StackTrace;          
}  

MyServiceContract

代码语言:javascript
复制
[ServiceContract]  
public interface IAddress  
{  
    [OperationContract]  
[FaultContract(typeof(FleetCustomException))]  
    bool SaveAddress(string address1, string address2, string address3, string city, string province, string postalCode,string country,bool isDeleted, int createdBy, DateTime createdDate, int lastModifiedBy, DateTime lastModifiedDate);  

    [OperationContract]  
[FaultContract(typeof(FleetCustomException))]  
    bool DeleteAddress(Int64 addressID, int lastModifiedBy);  

    [OperationContract]  
[FaultContract(typeof(FleetCustomException))]  
    List<Address> GetAllAddresses();  
}  

服务

代码语言:javascript
复制
public class SettingsService : IAddress  
{  

    #region IAddress Members  

    public bool SaveAddress(string address1, string address2, string address3, string city, string province,string postalCode,string country, bool isDeleted,int createdBy, DateTime createdDate, int lastModifiedBy, DateTime lastModifiedDate)  
    {  
        try  
        {  
            Address address = new Address(0, address1, address2, address3, city, province, postalCode, country, isDeleted,createdBy, createdDate, lastModifiedBy, lastModifiedDate);  
            return address.Insert();  

        }  
        catch (FaultException ex)  
        {  

          FleetCustomException ex = new FleetCustomException();  
          ex.Title = "Error Funtion:SaveAddress()";  
      ex.ExceptionMessage = "Error occur while doing save address function.";  
          ex.InnerException = "Inner exception message from serice";  
          ex.StackTrace = "Stack Trace message from service.";  
          throw new FaultException(ex,"Reason: Testing the Fault contract") ;  
        }  
    }     




    public bool DeleteAddress(Int64 addressID, int lastModifiedBy)  
    {  
        Address address = new Address(addressID, lastModifiedBy);  
        return address.Delete();  
    }  

    public List<Address> GetAllAddresses()  
    {  

        Address address = new Address();  
        return address.GetAllAddresses();  
    }  
    #endregion  

}

服务层includeExceptionDetailInFaults=中的<serviceDebug>“真”配置

代码语言:javascript
复制
<serviceDebug includeExceptionDetailInFaults="true"/>  

消耗法

代码语言:javascript
复制
   try  
   {  
      MySettingsService.SettingsService  proxy = new MySettingsService.SettingsService();
      proxy .SaveAddress(Address1TextBox.Text, Address2TextBox.Text, "", "", "", "641025", "", false, 1, DateTime.Now, 0, DateTime.Now);  
    }  
    catch (FaultException<MyCalculatorService.CustomException> ex)  
     {  
        //Process the Exception
     }  

我必须实现我所有的服务方法,我有超过100种方法,有什么方法可以快速而有效地实现它呢?

EN

回答 2

Stack Overflow用户

发布于 2012-01-03 18:11:15

FaultContract是处理错误的适当"SOAP“方法。SOAP标准定义了错误消息元素。

WCF的缺点是您需要在每个WCF服务操作上指定[FaultContract],所以如果您有很多方法,就必须定义很多地方。(实际上有一种方法可以在WCF服务启动时以编程方式添加故障契约,以避免在每个方法上声明它,如果我可以在某个地方挖掘代码.)

另外,如果您希望在WCF服务中有一些中心位置来处理错误,那么您可以实现IErrorHandler,当任何未处理的异常发生时,它都会被WCF调用。

或者,您可以通过这样一种方式来构造您的消息,即它们始终可以选择包含错误消息。例如:

代码语言:javascript
复制
[OperationContract]
SaveAddressResult SaveAddress(...);

[DataContract]
public class SaveAddressResult : Result
{
    [DataMember]
    public bool Success { get; set; }
}

[DataContract]
public class Result
{
    [DataMember]
    public string ErrorMessage { get; set; }
}

附加注意:将异常和堆栈跟踪发送回客户端是错误的做法!它可能包含堆栈跟踪信息或客户不应该知道的其他信息。例如,如果有一个服务方法试图使用SQL查询验证登录,而DB本身导致异常,则客户端可能会在查询引发的异常消息中取回表名和列名,甚至数据库名。您的异常消息应该始终被净化,并被简化为仅仅是客户需要的信息!

这方面的一个很好的例子是进入DB的任何字符串输入。做以下事情:

代码语言:javascript
复制
public Save(string someData)
{
    sqlCommand.Statement = "insert into myTable (myColumn) values (" + someData + ")";
    sqlCommand.Execute();
}

如果插入到is中的列允许假设为VARCHAR(256),并且用户现在向您的服务发送500个字符串,客户端将返回一个包含“值太大以致于列myTable.myColumn”之类的错误消息。这是客户永远不应该知道的实现和内部细节。

票数 0
EN

Stack Overflow用户

发布于 2012-12-12 18:18:09

实现System.ServiceModel.Dispatcher.IErrorHandler接口来处理集中处理的所有错误。

我建议您阅读这篇文章:http://www.codeproject.com/Articles/26320/WCF-Error-Handling-and-Fault-Conversion

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8715249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档