wcf中处理application/hal+json格式

Deal with application/hal+json format in wcf

我设置了一个已配置的 URL 端点(使用 wcf 和 POST 方法),以便在我的客户端发生某些事情时触发。当请求的内容类型设置为 application/json 时效果很好,但在设置时效果不佳到我的客户想要使用的 application/json+hal。 我的问题是如何处理这件事,我要改变什么。这是接口中我的方法的定义:

[WebInvoke(Method = "POST", UriTemplate = "/payload", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
string payload(requestpayload jsondata);

我更新了我的 web.config 以考虑@carlosfigueira 的建议:

<services>
      <service behaviorConfiguration="RestServiceBehavior" name="RestRaw.RestService">
        <endpoint address="http://mywebsite.com/RestService.svc" binding="customBinding" bindingConfiguration="RawReceiveCapable" contract="RestRaw.IRestService" behaviorConfiguration="Web">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="RestServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="Web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <customBinding>
        <binding name="RawReceiveCapable">
          <webMessageEncoding webContentTypeMapperType="RestRaw.JsonHalMapper, RestRaw" />
          <httpTransport manualAddressing="true"  />
        </binding>

      </customBinding>

但是,我得到这个:

500 System.ServiceModel.ServiceActivationException

有什么想法请

您可以使用 WebContentTypeMapper 向 WCF 指示您希望以与 "regular" JSON 相同的方式对待 application/hal+json(即 application/json)。下面的代码显示了使用映射器的示例。

public class Whosebug_37597194
{
    [ServiceContract]
    public interface ITest
    {
        [WebInvoke(Method = "POST",
            UriTemplate = "/payload",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Bare)]
        string payload(RequestPayload jsondata);
    }
    [DataContract]
    public class RequestPayload
    {
        [DataMember(Name = "_links")]
        public RequestPayloadLinks Links { get; set; }
        [DataMember(Name = "currency")]
        public string Currency { get; set; }
        [DataMember(Name = "status")]
        public string Status { get; set; }
        [DataMember(Name = "total")]
        public double Total { get; set; }
    }
    [DataContract] public class LinkObject
    {
        [DataMember(Name = "href")]
        public string Href { get; set; }
    }
    [DataContract]
    public class RequestPayloadLinks
    {
        [DataMember(Name = "self")]
        public LinkObject Self { get; set; }
        [DataMember(Name = "warehouse")]
        public LinkObject Warehouse { get; set; }
        [DataMember(Name = "invoice")]
        public LinkObject Invoice { get; set; }
    }
    public class Service : ITest
    {
        public string payload(RequestPayload jsondata)
        {
            return string.Format("{0} - {1} {2}", jsondata.Status, jsondata.Total, jsondata.Currency);
        }
    }
    public class JsonHalMapper : WebContentTypeMapper
    {
        public override WebContentFormat GetMessageFormatForContentType(string contentType)
        {
            if (contentType.StartsWith("application/hal+json"))
            {
                return WebContentFormat.Json;
            }
            else
            {
                return WebContentFormat.Default;
            }
        }
    }

    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        var endpoint = host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding { ContentTypeMapper = new JsonHalMapper() }, "");
        endpoint.EndpointBehaviors.Add(new WebHttpBehavior());
        host.Open();
        Console.WriteLine("Host opened");

        WebClient c = new WebClient();
        var requestData = @"   {
            '_links': {
                'self': { 'href': '/orders/523' },
                'warehouse': { 'href': '/warehouse/56' },
                'invoice': { 'href': '/invoices/873' }
            },
            'currency': 'USD',
            'status': 'shipped',
            'total': 10.20
        }".Replace('\'', '\"');
        Console.WriteLine(requestData);
        c.Headers[HttpRequestHeader.ContentType] = "application/hal+json";
        try
        {
            var response = c.UploadString(baseAddress + "/payload", "POST", requestData);
            Console.WriteLine(response);
        }
        catch (WebException ex)
        {
            Console.WriteLine("Exception: {0}", ex);
        }

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}