2011-08-01 2 views
10

Z zamówienia:Spożywanie WCF z jQuery jako JSON

namespace ACME.FooServices 
{ 
    [ServiceContract] 
    public interface IFooService 
    { 
     [OperationContract] 
     [WebInvoke(Method = "POST", 
        ResponseFormat = WebMessageFormat.Json, 
        RequestFormat = WebMessageFormat.Json, 
        BodyStyle = WebMessageBodyStyle.Bare)]   
     FooMessageType Foo(string name); 
    } 

    [DataContract] 
    public class FooMessageType 
    { 
     string _name; 
     string _date; 

     [DataMember] 
     public string Name 
     { 
      get { return _name; } 
      set { _name = value; } 
     } 

     [DataMember] 
     public string Date 
     { 
      get { return _date; } 
      set { _date = value; } 
     } 
    } 
} 

i realizacja:

using System; 
using System.ServiceModel.Activation; 

namespace ACME.FooServices 
{ 
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 
    public class FooService : IFooService 
    { 
     public FooMessageType Foo(string name) 
     { 
      string l_name = (String.IsNullOrWhiteSpace(name)) ? "Anonymous" : name; 

      return new FooMessageType {Name = l_name, Date = DateTime.Now.ToString("MM-dd-yyyy h:mm:ss tt")}; 
     } 
    } 
} 

skonfigurowane w pliku web.config jako:

<system.serviceModel> 
    <services> 
     <service name="ACME.FooServices.FooService"> 
      <endpoint address="" behaviorConfiguration="ACME.FooBehaviour" binding="webHttpBinding" contract="ACME.FooServices.IFooService" /> 
     </service> 
    </services> 
    <behaviors> 
     <endpointBehaviors> 
      <behavior name="ACME.FooBehaviour"> 
       <webHttp /> 
      </behavior> 
     </endpointBehaviors> 
     <serviceBehaviors> 
      <behavior name=""> 
       <serviceMetadata httpGetEnabled="true" /> 
       <serviceDebug includeExceptionDetailInFaults="true" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
</system.serviceModel> 

Próbuję zadzwoń do Foo ze strony za pośrednictwem jQuery:

<script type="text/javascript" language="javascript"> 
    $(document).ready(function() { 
     $("#msgButton").click(function() { 
      var params = {}; 
      params.name = $("#nameTextbox").val(); 

      $.ajax({ 
       type: 'POST', 
       url: "http://acme.com/wcfsvc/FooService.svc/Foo", 
       data: JSON.stringify(params), 
       contentType: 'application/json; charset=utf-8', 
       success: function (response, status, xhr) { alert('success: ' + response); }, 
       error: function (xhr, status, error) { alert("Error\n-----\n" + xhr.status + '\n' + xhr.responseText); }, 
       complete: function (jqXHR, status) { alert('Status: ' + status + '\njqXHR: ' + JSON.stringify(jqXHR)); } 
      }); 
     }); 
    });   
</script> 

Ale otrzymuję komunikat o błędzie 400 - Nieprawidłowe żądanie z komunikatem "Serwer napotkał błąd podczas przetwarzania żądania. Komunikat o wyjątku to "Wystąpił błąd podczas deserializacji obiektu typu System.String. Koniec elementu "root" z przestrzeni nazw "oczekiwano. Znaleziony element 'name' z nazw”.

Am I czegoś brakuje?

Odpowiedz

15

Twój params jest przedmiot i tworzy { "name" : "someValue" } JSON ciąg. Jeśli powiesz, że styl wiadomości jest następujący: Bare Myślę, że twoja usługa spodziewa się czegoś takiego:

[DataContract] 
public class SomeDTO 
{ 
    [DataMember(Name = "name")] 
    public string Name { get; set; } 
} 

I dlatego, że operacja powinna być określona zdefiniowana jako:

[OperationContract] 
[WebInvoke(Method = "POST", 
      ResponseFormat = WebMessageFormat.Json, 
      RequestFormat = WebMessageFormat.Json, 
      BodyStyle = WebMessageBodyStyle.Bare)]   
FooMessageType Foo(SomeDTO data); 

Jeśli chcesz, aby Twój aktualny kod do pracy powinieneś go zmienić na:

[OperationContract] 
[WebInvoke(Method = "POST", 
      ResponseFormat = WebMessageFormat.Json, 
      RequestFormat = WebMessageFormat.Json, 
      BodyStyle = WebMessageBodyStyle.WrappedRequest)]   
FooMessageType Foo(SomeDTO data); 
+0

wnoszę Nagie i DTO byłoby najlepiej ćwiczyć? – Bullines

4

Spróbuj ustawić BodyStyle=WebMessageBodyStyle.Wrapped

source

6

mam ten sam problem. po ustawieniu BodyStyle = WebMessageBodyStyle.Wrapped został rozwiązany.

[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] 
+0

To, co Ladislav Mrnka zasugerował, jest pracą. Ale BodyStyle = WebMessageBodyStyle.Wrapped to dobra poprawka –

0

Nadwozie = WebMessageBodyStyle.WrappedRequest pracował dla mnie, jeśli żądasz od Skrzypek lub inny odpoczynku klientów ale jeśli żądasz od HTTPWebResponse Bare będzie pracować