Разобраться с применением / форматом hal+json в 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

любая мысль, пожалуйста

1 ответ

Решение

Вы можете использовать WebContentTypeMapper, чтобы указать WCF, что вы хотите лечить application/hal+json так же, как "обычный" JSON (то есть application/json). Код ниже показывает пример использования картографа.

public class Stackru_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();
    }
}
Другие вопросы по тегам