2011-09-21 53 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