WCF异常处理#2

3
我有很多个WCF服务方法,我想实现异常处理。我的服务将被.NET和非.NET客户端使用。故障契约是否是实现异常处理的唯一方法?如果是这样,我如何避免在我的服务中实现所有方法。我如何在一个地方实现异常处理以处理服务中所有方法的异常。请提供一些代码以便于理解。
以下是我的示例代码:
我的故障契约
[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  

服务层中的配置包括在 <serviceDebug> 中设置 includeExceptionDetailInFaults="true"。


<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多个,有没有一种快速且有效的方法来实现它?


你想完成什么?完全不处理异常有什么问题吗? - John Saunders
嗨John,如果我只处理异常,那么不在.NET框架中的其他程序将无法理解该异常。因此,WCF故障契约将发送基于XML SOAP的异常。 - santhosh
1
仍然会有一个SOAP故障,只是不会有详细的故障信息。 - John Saunders
2个回答

0

0

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

在WCF中,这样做的缺点是您需要在每个WCF服务操作上指定,因此如果您有很多方法,则必须在许多地方定义它。 (实际上,有一种方法可以在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名称。您的异常消息应始终经过清理,并剥离为客户需要的信息!

其中一个很好的例子是任何输入到DB的字符串。像这样做:

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

如果插入的列是 VARCHAR(256),而用户现在发送给您的服务一个 500 个字符的字符串,客户端将会收到一个故障消息,其中包含类似于“值太大,无法适应 myTable.myColumn 列”的内容。这是实现和内部细节,您的客户端不应该知道。

1
在WCF中,最好的异常处理方式是什么? - santhosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接