2

在 IIS 中运行但通过工厂运行的 Web 服务无法跟上引发的原始异常。

例如:

我的 Web 服务已用 FaultContractAttribute 标记,如下所示:

public interface IMyService
{
    [FaultContract(typeof(MyCustomException))]
    [OperationContract]
    bool IsAuthorized();
}

我的 Web 服务实现抛出了一个自定义异常,如下所示:

public class MyService : IMyService
{
    public bool IsAuthorized()
    {
        throw new FaultException<MyCustomException>(fault, fr);
    }
}

然后:

  1. 如果我的 WCF - 不使用任何工厂 - 类似于<%@ ServiceHost Language="C#" Debug="true" Service="MyService" %>,那么在客户端我可以获取原始异常 (MyCustomException)

  2. <%@ ServiceHost Language="C#" Debug="true" Service="MyService" Factory="MyFactory" %>如果我的 WCF - USING some factory - 类似于

笔记:

WCF 工厂 MyFactory 是通过其 SERVICE HOST 实现的,其中包含从 IErrorHandler 启动的 SERVICE BEHAVIOR

在这种服务行为中,ProvideFault 方法什么都不做(我不知道如何通过这种方式保持原始异常)

总之,我希望得到期望的答案:如何在使用某些 WCF 工厂时保持原始异常(MyCustomException)?谢谢。

4

1 回答 1

1

在我最近的项目(WCF REST 服务)中,我使用了WebServiceHostFactory并且我仍然能够使用IErrorHandler来实现这一点。在下面查找示例

我创建了一个可以序列化并发送回客户端的类 ExceptionInfo。

[Serializable]
public class ExceptionInfo
{
    public string ExceptionType { get; set; }
    public string ExceptionMessage { get; set; }
    public string StackTrace { get; set; }
}

并实现自定义错误处理程序

[DataContract]
public class MyCustomServiceErrorHandler : IErrorHandler
{
    #region IErrorHandler Members

    /// <summary>
    /// This method will execute whenever an exception occurs in WCF method execution
    /// </summary>
    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        var exceptionInfo = new ExceptionInfo();

        if (error is MyCustomException)
            exceptionInfo.ExceptionType = error.Type.ToString();;
        else
            exceptionInfo.Type = "Unhandled Exception";

        exceptionInfo.ExceptionMessage = error.Message;            
        exceptionInfo.StackTrace = error.StackTrace;

        var faultException = new FaultException<ExceptionInfo>(exceptionInfo);

        object detail = faultException.GetType().GetProperty("Detail").GetGetMethod().Invoke(faultException, null);

        fault = Message.CreateMessage(version, "", detail, new DataContractSerializer(detail.GetType()));

        var webBodyFormatMessageProp = new WebBodyFormatMessageProperty(WebContentFormat.Xml);

        fault.Properties.Add(WebBodyFormatMessageProperty.Name, webBodyFormatMessageProp);

        var httpResponseMessageProp = new HttpResponseMessageProperty();

        httpResponseMessageProp.Headers[HttpResponseHeader.ContentType] = "application/xml";
        httpResponseMessageProp.StatusCode = HttpStatusCode.BadRequest;
        httpResponseMessageProp.StatusDescription = exceptionInfo.ExceptionMessage;

        fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponseMessageProp);

    }

    /// <summary>
    /// Performs error related behavior
    /// </summary>
    /// <param name="error">Exception raised by the program</param>
    /// <returns></returns>
    public bool HandleError(Exception error)
    {
        // Returning true indicates that an action(behavior) has been taken (in ProvideFault method) on the exception thrown.
        return true;
    }

现在您可以使用上面的处理程序来装饰您的服务。

[ServiceContract]    
[ServiceErrorBehavior(typeof (MyCustomServiceErrorHandler))]
public class LoginService : ServiceBase
{}

在客户端,您可以检查响应的 HttpStatusCode 是否 != Ok 并将响应反序列化为 ExceptionInfo 类型并显示在消息框中或按要求处理。

希望这可以帮助。

于 2012-04-06T16:58:40.583 回答