2011-09-21 55 views
0

对于任何webprotocol异常,errorhandler应该处理异常并只给出json响应,而不是给出页面未找到。IErrorHandler在页面中找不到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(); 
     } 
    } 
} 

回答

0

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

+0

我试图从浏览器中运行服务,只需输入URL和json响应,如果有异常,那么它会给文件找不到。这是期望的结果吗?虽然它在ajax调用中工作正常。 – Nayan

+0

检查您在浏览器上发送的URL与AJAX调用中的URL;服务器不知道(或关心)请求来自哪里。 – carlosfigueira

+0

我修改了这样的服务public Person GetPerson() {throw new WebProtocolException {StatusCode = System.Net.HttpStatusCode.Conflict,StatusDescription =“Conflict”};}对于浏览器中的Json调用,找不到文件。但Ajax调用工作正常。在这些情况下,URL是相同的:http://localhost/SO_7498771/RestService.svc/json/GetPerson,但POX调用在ajax和Browser中都可以正常工作,URL是http://localhost/SO_7498771/RestService.svc/pox/GetPerson – Nayan