Wcf服务exception良好做法
我正在开发分布式应用程序。 在其中,我必须validation角色和权限集。
在例如未经授权的访问中抛出exception是一个很好的实践吗?
或者我应该将一些消息发回给客户?
在您的服务操作中,您可以指定一个FaultContract ,它将同时满足这两个目的:
[OperationContract] [FaultContract(typeof(MyServiceFault))] void MyServiceOperation();
请注意,MyServiceFault必须使用与复杂类型相同的方式标记DataContract和DataMember属性:
[DataContract] public class MyServiceFault { private string _message; public MyServiceFault(string message) { _message = message; } [DataMember] public string Message { get { return _message; } set { _message = value; } } }
在服务方面,您可以:
throw new FaultException(new MyServiceFault("Unauthorized Access"));
在客户端:
try { ... } catch (FaultException fault) { // fault.Detail.Message contains "Unauthorized Access" }
好吧,您可以捕获WCF服务实现方法中的所有exception,并将它们重新抛出为FaultExceptions。 通过这种方式,将在客户端上重新抛出exception,并显示您选择的消息:
[OperationContract] public List GetAllCustomers() { try { ... code to retrieve customers from datastore } catch (Exception ex) { // Log the exception including stacktrace _log.Error(ex.ToString()); // No stacktrace to client, just message... throw new FaultException(ex.Message); } }
为了避免将意外错误转发回客户端,从不在服务器端的代码中抛出exception实例也是一种好习惯。 而是创建一个或多个自己的exception类型并抛出它们。 通过这样做,您可以区分意外的服务器处理错误和由于无效请求而引发的错误等:
public List GetAllCustomers() { try { ... code to retrieve customers from datastore } catch (MyBaseException ex) { // This is an error thrown in code, don't bother logging it but relay // the message to the client. throw new FaultException(ex.Message); } catch (Exception ex) { // This is an unexpected error, we need log details for debugging _log.Error(ex.ToString()); // and we don't want to reveal any details to the client throw new FaultException("Server processing error!"); } }
如果你没有使用basicHTTPBinding,抛出一般的Dot Net Exceptions会使服务客户端代理和服务器通道进入故障状态…为了避免这种情况,你应该总是从服务中抛出FaultException …来自catch块只需使用:
throw new FaultException("Your message to the clients");