【问题标题】:WCF Exception Handling #2WCF 异常处理 #2
【发布时间】:2012-01-03 16:24:08
【问题描述】:

我有 N 个 WCF 服务方法。我想实现异常处理。我的服务将被 .net 和非 .net 客户端使用。故障契约是实现异常处理的唯一方法吗?如果这意味着我如何避免实现我的服务中的所有方法。我如何在一个地方实现异常处理来处理我的服务中所有方法的异常。请提供一些代码集以轻松稳定。

这是我的示例代码。


MyFaultContract


[DataContract()]  
public class FleetCustomException  
{  
    [DataMember()]  
    public string Title;  
    [DataMember()]  
    public string ExceptionMessage;  
    [DataMember()]  
    public string InnerException;  
    [DataMember()]  
    public string StackTrace;          
}  

我的服务合同


[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();  
}  

服务


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  

}

Service 层中的配置 includeExceptionDetailInFaults="true" in &lt;serviceDebug&gt;


<serviceDebug includeExceptionDetailInFaults="true"/>  

消费方式

   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 种方法有什么方法可以快速有效地实现它

【问题讨论】:

  • 你想完成什么?根本不处理异常有什么问题?
  • 嗨,约翰,如果我只处理异常。不在 .net 框架中的其他程序将无法理解该异常。这样 WCF 故障合同将发送基于 XML 肥皂的异常。
  • 还是会出现 SOAP 故障,只是没有详细说明。

标签: wcf


【解决方案1】:

FaultContract 是处理错误的适当“SOAP”方式。 SOAP 标准定义了故障消息元素。

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

此外,如果您希望某个中心位置来处理 WCF 服务中的错误,您可以实现 IErrorHandler,当发生任何未处理的异常时,WCF 将调用它。


或者,您可以将消息构造为始终可以选择包含错误消息的方式。例如:

[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 名称.您的异常消息应始终进行清理,并精简为客户需要的信息!

一个很好的例子是进入数据库的任何字符串输入。做类似的事情:

public Save(string someData)
{
    sqlCommand.Statement = "insert into myTable (myColumn) values (" + someData + ")";
    sqlCommand.Execute();
}

如果插入的列是VARCHAR(256),并且用户现在向您的服务发送一个 500 个字符的字符串,则客户端将返回一条错误消息,其中包括“myTable.myColumn 列的值太大” ”。这是您的客户永远不应该知道的实现和内部细节。

【讨论】:

  • wcf 中异常处理的最佳方式是什么。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 2023-03-10
    • 2012-06-10
    • 2013-07-31
    相关资源
    最近更新 更多