2016-06-02 17 views
0

Ich eingerichtet einen konfigurierten URL Endpunkt (mit der Methode wcf und POST) ausgelöst werden, wenn etwas auf meiner Client-Seite geschieht. es funktioniert gut, wenn der Inhaltstyp, für den Antrag, zu application/json gesetzt, aber es funktioniert nicht, wenn es um application/json + hal, die mein Kunde nutzen möchte, eingestellt ist. Meine Frage ist, wie ich mit dieser Angelegenheit umgehen soll und was ich ändern muss. Hier ist die Definition meiner Methode in der Schnittstelle:Umgang mit Anwendung/Hal + JSON-Format in wcf

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

ich meine aktualisiert web.config @carlosfigueira Vorschlag in Betracht zu ziehen:

<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> 

Allerdings erhalte ich diese:

500 System.ServiceModel.ServiceActivationException

jeder Gedanke bitte

Antwort

0

Sie einen WebContentTypeMapper zu WCF, um anzuzeigen, verwenden können, die Sie application/hal+json genauso wie „normale“ JSON (das heißt, application/json) behandeln wollen. Der folgende Code zeigt ein Beispiel für die Verwendung des Mappers.

public class StackOverflow_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(); 
    } 
} 
+0

Vielen Dank @carlosfigueira, ich habe Ihren Vorschlag versucht. Allerdings bekomme ich das: ** 500 System.ServiceModel.ServiceActivationException ** –

+0

Was ist der Körper der Aktivierung Ausnahmeantwort? Gibt es weitere Details zu der Ausnahme? Oder Sie können die Ablaufverfolgung aktivieren, und Sie sollten sehen, warum der Dienst nicht geöffnet werden konnte. – carlosfigueira

+0

Ich habe mein Problem behoben. Im Allgemeinen habe ich ** WebContentTypeMapper ** verwendet, wie @carlosfigueira sagte. dann habe ich meine web.config wie oben erwähnt geändert, aber mit diesem Update: ** ** –