2013-02-21 59 views
0

的open311協議需要用於以下列格式端點支持:WCF自定義錯誤處理程序有條件地返回XML或JSON?

  • 域/ requests.xml
  • 域/ requests.json

的第一端點接受XML請求,所述第二請求JSON 。

協議進一步指定錯誤應以請求格式(xml或json)返回。

在實現ServiceBehaviorErrorHandler時,我發現無法確定ProvideFault方法中的請求格式(xml或json)。所有示例或者返回json xml。

如何確定請求格式,以便能夠以相同格式返回錯誤消息?我的實現:

/// <summary> 
/// From http://www.codeproject.com/Articles/43621/Extending-WCF-Part-I 
/// </summary> 
public class ExtendedServiceErrorHandler : IErrorHandler, IServiceBehavior 
{ 
    #region IErrorHandler Members 

    bool IErrorHandler.HandleError(Exception error) 
    { 
     return (error is Open311Exception); 
    } 

    /* 
    * TODO: HTTP error codes are required, but the code in the response body shouldn't necessarily match the HTTP error code, 
    * so that more specific and unique error code identifiers can be used. 
    * The HTTP error codes should always be 404 for resources that don't exist, 
    * 403 for errors because of wrong or missing api_key and basically 
    * 400 for any other error where the request can not be fulfilled as expected. 
    * Multiple errors codes and descriptions can be returned in the body (the response is an array). 
    */ 
    void IErrorHandler.ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     var ajaxErrors = new AjaxErrors(); 
     var open311Error = error as Open311Exception; 
     if(null != open311Error) 
     { 
      ajaxErrors.Add(new AjaxError() 
       { 
        Code = open311Error.Code, 
        Message = open311Error.Message 
       }); 
     } 
     else 
     { 
      ajaxErrors.Add(new AjaxError() 
       { 
        Code = 400, 
        Message = error.Message 
       }); 
     } 
     var contentType = "application/json"; // TODO: how do we know? 
     // WebOperationContext.Current.IncomingRequest.ContentType doesn't work 
     WebContentFormat webContentFormat; 
     switch(contentType) 
     { 
      case "application/json": 
       fault = Message.CreateMessage(version, string.Empty, ajaxErrors, new DataContractJsonSerializer(ajaxErrors.GetType())); 
       webContentFormat = WebContentFormat.Json; 
       break; 
      case "application/xml": 
       fault = Message.CreateMessage(version, string.Empty, ajaxErrors, new DataContractSerializer(ajaxErrors.GetType())); 
       webContentFormat = WebContentFormat.Xml; 
       break; 
      default: 
       fault = Message.CreateMessage(version, string.Empty, ajaxErrors, new DataContractSerializer(ajaxErrors.GetType())); 
       webContentFormat = WebContentFormat.Raw; 
       break; 
     } 
     var wbf = new WebBodyFormatMessageProperty(webContentFormat); 
     fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf); 
     WebOperationContext.Current.OutgoingResponse.ContentType = contentType; 
     WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.OK; // HttpStatusCode.BadRequest; 
    } 

    #endregion 

    #region IServiceBehavior Members 

    void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) 
    { 
     // nothing to do? 
    } 

    void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) 
    { 
     var errorHandler = new ExtendedServiceErrorHandler(); 

     foreach(ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers) 
     { 
      channelDispatcher.ErrorHandlers.Add(errorHandler); 
     } 
    } 

    void IServiceBehavior.Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) 
    { 
     // nothing to do? 
    } 

    #endregion 
} 

回答

相關問題