0

open311 协议需要支持以下格式的端点:

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

第一个端点接受 xml 请求,第二个 json 请求。

协议进一步指定错误应该以请求格式(xml 或 json)返回。

在实现 ServiceBehaviorErrorHandler 时,我发现无法在 ProvideFault 方法中确定请求格式(xml 或 json)。所有示例都返回 jsonxml。

如何确定请求格式,以便以相同格式返回错误消息?我的实现:

    /// <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
}
4

1 回答 1

2

我相信这就是你要找的东西:http: //msdn.microsoft.com/en-us/library/vstudio/ee513227 (v=vs.100).aspx

Windows Communication Foundation (WCF) Web HTTP 错误处理使您能够从指定 HTTP 状态代码的 WCF Web HTTP 服务返回错误,并使用与操作相同的格式(例如 XML 或 JSON)返回错误详细信息。

于 2013-02-22T21:26:27.713 回答