C# Wcf 服务异常良好实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12647615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wcf service exception good practices
提问by marcelo-ferraz
I am developing a distributed application. In it, there are roles and sets of permissions that I must validate.
Is a good pratice to throw an exception, in per example, unauthorized access?
Or should I send some message back to the client?
我正在开发分布式应用程序。在其中,我必须验证角色和权限集。在每个示例中,未经授权的访问
是抛出异常的好习惯吗?
或者我应该向客户端发送一些消息?
采纳答案by Traxxus
On your service operation, you can specify a FaultContractthat will serve both purposes like so:
在您的服务操作中,您可以指定一个同时服务于两个目的的FaultContract,如下所示:
[OperationContract]
[FaultContract(typeof(MyServiceFault))]
void MyServiceOperation();
Note that MyServiceFault must be marked with DataContract and DataMember attributes, in the same way you would a complex type:
请注意,必须使用 DataContract 和 DataMember 属性标记 MyServiceFault,就像标记复杂类型一样:
[DataContract]
public class MyServiceFault
{
private string _message;
public MyServiceFault(string message)
{
_message = message;
}
[DataMember]
public string Message { get { return _message; } set { _message = value; } }
}
On the service-side, you are then able to:
在服务方面,您可以:
throw new FaultException<MyServiceFault>(new MyServiceFault("Unauthorized Access"));
And on the client-side:
而在客户端:
try
{
...
}
catch (FaultException<MyServiceFault> fault)
{
// fault.Detail.Message contains "Unauthorized Access"
}
回答by Daniel Persson
Well, you can catch all exceptions in the WCF service implementations methods and rethrow them as FaultExceptions. By doing it this way, the exception will be rethrown on the client with a message of your choosing:
好吧,您可以捕获 WCF 服务实现方法中的所有异常,并将它们作为 FaultExceptions 重新抛出。通过这样做,异常将在客户端上重新抛出,并带有您选择的消息:
[OperationContract]
public List<Customer> 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);
}
}
To avoid having unexpected errors relayed back to the client, it's also a good practice to never throw Exception instances in code on the server-side. Instead create one or more of your own exception types and throw them. By doing so, you can distinguish between unexpected server processing errors and errors that are thrown due to invalid requests etc:
为了避免将意外错误转发回客户端,最好不要在服务器端的代码中抛出异常实例。而是创建一种或多种您自己的异常类型并抛出它们。通过这样做,您可以区分意外的服务器处理错误和由于无效请求等引发的错误:
public List<Customer> 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!");
}
}
回答by khaled4vokalz
Throwing general Dot Net Exceptions would make the service client proxies and the server channel to go in faulted state if you are not using basicHTTPBinding...To avoid that you should always throw FaultExceptionfrom the service... from you catch block just use:
如果您不使用basicHTTPBinding,则抛出一般的 Dot Net Exceptions 将使服务客户端代理和服务器通道进入故障状态……为避免您应该始终从服务中抛出FaultException……从您的 catch 块中,只需使用:
throw new FaultException("Your message to the clients");

