IErrorHandler在休息时为Json响应找不到页面

时间:2011-09-21 11:12:34

标签: wcf ierrorhandler

对于任何webprotocol异常,错误处理程序应该处理异常并仅提供json响应,而不是找不到页面。

以下是服务的配置

    <system.serviceModel>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
      <extensions>
        <behaviorExtensions>
          <add name="enhancedWebHttp" type="Licensing.Services.EnhancedWebHttpElement, Licensing.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
        </behaviorExtensions>
      </extensions>
      <bindings>
        <webHttpBinding>
          <binding name="webBinding">
          </binding>
        </webHttpBinding>
      </bindings>
      <behaviors>
        <endpointBehaviors>
          <behavior name="jsonBehavior">
            <enhancedWebHttp defaultOutgoingResponseFormat="Json"/>
          </behavior>
          <behavior name="poxBehavior">
            <enhancedWebHttp/>
          </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
          <behavior name="Licensing.Services.restserviceBehavior" >
            <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
            <serviceMetadata httpGetEnabled="true"/>
            <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
            <serviceDebug includeExceptionDetailInFaults="false"/>
          </behavior>
        </serviceBehaviors>
      </behaviors>
      <services>
        <service name="Licensing.Services.restservice" behaviorConfiguration="Licensing.Services.restserviceBehavior">
          <host>
            <baseAddresses>
              <add baseAddress="http://localhost/LicensingAPIService/restservice.svc"/>
            </baseAddresses>
          </host>
          <endpoint address="json" binding="webHttpBinding" bindingConfiguration="webBinding" behaviorConfiguration="jsonBehavior"
          contract="Licensing.Services.IRestService" />
          <endpoint address="pox" binding="webHttpBinding" bindingConfiguration="webBinding" behaviorConfiguration="poxBehavior"
          contract="Licensing.Services.IRestService"/>
        </service>
      </services>
    </system.serviceModel>

以下是enhancedWebHttp的代码

public sealed class EnhancedWebHttpElement : BehaviorExtensionElement
{
    #region Type specific properties

    [ConfigurationProperty("defaultBodyStyle", DefaultValue = WebMessageBodyStyle.Bare)]
    public WebMessageBodyStyle DefaultBodyStyle
    {
        get
        {
            return (WebMessageBodyStyle)this["defaultBodyStyle"];
        }

        set
        {
            this["defaultBodyStyle"] = value;
        }
    }

    [ConfigurationProperty("defaultOutgoingRequestFormat", DefaultValue = WebMessageFormat.Xml)]
    public WebMessageFormat DefaultOutgoingRequestFormat
    {
        get
        {
            return (WebMessageFormat)this["defaultOutgoingRequestFormat"];
        }

        set
        {
            this["defaultOutgoingRequestFormat"] = value;
        }
    }

    [ConfigurationProperty("defaultOutgoingResponseFormat", DefaultValue = WebMessageFormat.Xml)]
    public WebMessageFormat DefaultOutgoingResponseFormat
    {
        get
        {
            return (WebMessageFormat)this["defaultOutgoingResponseFormat"];
        }

        set
        {
            this["defaultOutgoingResponseFormat"] = value;
        }
    }

    #endregion

    #region Base class overrides

    protected override object CreateBehavior()
    {
        LicensingBehavior result = new LicensingBehavior();

        result.DefaultBodyStyle = this.DefaultBodyStyle;
        result.DefaultOutgoingRequestFormat = this.DefaultOutgoingRequestFormat;
        result.DefaultOutgoingResponseFormat = this.DefaultOutgoingResponseFormat;
        return result;
    }

    public override Type BehaviorType
    {
        get
        {
            return typeof(LicensingBehavior);
        }
    }

    #endregion
} 

以下是许可行为的代码

public class LicensingBehavior : WebHttpBehavior
{

    protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        int errorHandlerCount = endpointDispatcher.ChannelDispatcher.ErrorHandlers.Count;
        base.AddServerErrorHandlers(endpoint, endpointDispatcher);
        IErrorHandler webHttpErrorHandler = endpointDispatcher.ChannelDispatcher.ErrorHandlers[errorHandlerCount];
        endpointDispatcher.ChannelDispatcher.ErrorHandlers.RemoveAt(errorHandlerCount);
        RestErrorHandler newHandler = new RestErrorHandler(webHttpErrorHandler,DefaultOutgoingResponseFormat);
        endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(newHandler);
    }        

}

以下是ErrorHandler的代码。

public class RestErrorHandler : IErrorHandler
{
    IErrorHandler _originalErrorHandler;
    WebMessageFormat _format;
    public RestErrorHandler(IErrorHandler originalErrorHandler,WebMessageFormat format)
    {
        this._originalErrorHandler = originalErrorHandler;
        this._format = format;
    }

    public bool HandleError(Exception error)
    {
        return error is WebProtocolException;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        WebProtocolException licensingException = error as WebProtocolException;
        if (licensingException != null)
        {

            fault = Message.CreateMessage(version, null, new ValidationErrorBodyWriter(licensingException));
            if (_format == WebMessageFormat.Json)
            {
                HttpResponseMessageProperty prop = new HttpResponseMessageProperty();
                prop.StatusCode = licensingException.StatusCode;
                prop.Headers[HttpResponseHeader.ContentType] = "application/json; charset=utf-8";
                fault.Properties.Add(HttpResponseMessageProperty.Name, prop);
                fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
            }
            else if(_format == WebMessageFormat.Xml)
            {
                HttpResponseMessageProperty prop = new HttpResponseMessageProperty();
                prop.StatusCode = licensingException.StatusCode;
                prop.Headers[HttpResponseHeader.ContentType] = "application/xml; charset=utf-8";
                fault.Properties.Add(HttpResponseMessageProperty.Name, prop);
                fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Xml));
            }
        }
        else
        {
            this._originalErrorHandler.ProvideFault(error, version, ref fault);
        }
    }

    class ValidationErrorBodyWriter : BodyWriter
    {
        private WebProtocolException validationException;
        Encoding utf8Encoding = new UTF8Encoding(false);

        public ValidationErrorBodyWriter(WebProtocolException validationException)
            : base(true)
        {
            this.validationException = validationException;
        }

        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            writer.WriteStartElement("root");
            writer.WriteAttributeString("type", "object");

            writer.WriteStartElement("StatusCode");
            writer.WriteAttributeString("type", "string");
            writer.WriteString(this.validationException.StatusCode.ToString());
            writer.WriteEndElement();

            writer.WriteStartElement("Description");
            writer.WriteAttributeString("type", "string");
            writer.WriteString(this.validationException.StatusDescription);
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我创建了一个空的ASP.NET项目,复制了你所拥有的确切代码(更改了一些命名空间,没有任何应该影响结果的东西),并且它运行得很好 - 在“json”端点中,WebProtocolException是以JSON格式返回,而在“pox”端点中,以XML格式返回相同的异常。您可以从https://skydrive.live.com/?cid=99984bbbec66d789&sc=documents&uc=1&id=99984BBBEC66D789%21944#下载该项目(称为SO_7498771.zip),并将其与您的实现进行比较,看看是否有任何不同。