我有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;
} MyServiceContract
[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 }
服务层includeExceptionDetailInFaults=中的<serviceDebug>“真”配置
<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种方法,有什么方法可以快速而有效地实现它呢?
发布于 2012-01-03 18:11:15
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();
}如果插入到is中的列允许假设为VARCHAR(256),并且用户现在向您的服务发送500个字符串,客户端将返回一个包含“值太大以致于列myTable.myColumn”之类的错误消息。这是客户永远不应该知道的实现和内部细节。
发布于 2012-12-12 18:18:09
实现System.ServiceModel.Dispatcher.IErrorHandler接口来处理集中处理的所有错误。
我建议您阅读这篇文章:http://www.codeproject.com/Articles/26320/WCF-Error-Handling-and-Fault-Conversion
https://stackoverflow.com/questions/8715249
复制相似问题