0

open311プロトコルでは、次の形式のエンドポイントをサポートする必要があります。

  • domain / requests.xml
  • domain / requests.json

最初のエンドポイントはxmlリクエストを受け入れ、2番目のエンドポイントは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
}
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 に答える