2011-08-01 32 views
10

Với hợp đồng:Tiêu thụ WCF từ jQuery như 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; } 
     } 
    } 
} 

Và thực hiện:

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")}; 
     } 
    } 
} 

Configured trong web.config như:

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

Tôi đang cố gắng để gọi Foo từ một trang qua 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> 

Nhưng tôi nhận được 400 - Yêu cầu không hợp lệ lỗi với thông báo "Máy chủ đã gặp lỗi khi xử lý yêu cầu. Thông báo ngoại lệ là 'Có lỗi khi deserializing đối tượng của kiểu System.String. Kết thúc phần tử 'root' từ không gian tên '' được mong đợi. Tìm thấy nguyên tố 'tên' từ namespace".

Tôi có thiếu cái gì?

Trả lời

15

bạn params là đối tượng và nó tạo { "name" : "someValue" } JSON chuỗi. Nếu bạn nói rằng phong cách nội dung thư là Bare Tôi nghĩ dịch vụ của bạn trông đợi như sau:

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

Và vì lý do đó hoạt động của bạn cần được xác định định nghĩa là:

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

Nếu bạn muốn mã hiện tại của bạn để làm việc có lẽ bạn nên thay đổi nó thành:

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

tôi thu thập Bare và một DTO sẽ là một tốt nhất thực hành? – Bullines

4

Hãy thử thiết lập BodyStyle=WebMessageBodyStyle.Wrapped

source

6

tôi đã nhận cùng một vấn đề. sau khi thiết lập BodyStyle = WebMessageBodyStyle.Wrapped nó được giải quyết.

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

Những gì Ladislav Mrnka đề nghị là một công việc xung quanh.But BodyStyle = WebMessageBodyStyle.Wrapped là một sửa chữa đúng –

0

bodystyle = WebMessageBodyStyle.WrappedRequest làm việc cho tôi nếu bạn đang yêu cầu từ cáy hoặc phần còn lại khác khách hàng nhưng nếu bạn đang yêu cầu từ HttpWebResponse Bare sẽ được làm việc

Các vấn đề liên quan