33

我正在开发一个分布式应用程序。在其中,我必须验证角色和权限集。
抛出异常(例如未经授权的访问)是一种好习惯吗?
或者我应该向客户发送一些消息?

4

3 回答 3

58

在您的服务操作中,您可以指定一个能同时满足这两个目的的FaultContract ,如下所示:

[OperationContract]
[FaultContract(typeof(MyServiceFault))]
void MyServiceOperation();

请注意,必须使用 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; } }
}

在服务端,您可以:

throw new FaultException<MyServiceFault>(new MyServiceFault("Unauthorized Access"));

在客户端:

try
{
    ...
}
catch (FaultException<MyServiceFault> fault)
{
    // fault.Detail.Message contains "Unauthorized Access"
}
于 2012-09-28T22:05:09.250 回答
12

好吧,您可以在 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);
    }
}

为了避免将意外错误转发回客户端,最好不要在服务器端的代码中抛出异常实例。而是创建一种或多种您自己的异常类型并抛出它们。通过这样做,您可以区分意外的服务器处理错误和由于无效请求等引发的错误:

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!");
    }
}
于 2012-09-28T22:12:25.053 回答
3

如果您不使用basicHTTPBinding,则抛出一般的 Dot Net 异常会使服务客户端代理和服务器通道进入故障状态...为了避免您应该始终从服务中抛出FaultException ... 从您的 catch 块中使用:

throw new FaultException("Your message to the clients");
于 2016-12-03T11:01:10.117 回答