2009-02-26 27 views
22

Tôi sử dụng mã sau để gọi dịch vụ wcf. Nếu tôi gọi một phương thức (test) không có tham số, nhưng trả về một chuỗi nó hoạt động tốt. Nếu tôi thêm một tham số để phương pháp của tôi tôi nhận được một lỗi lạ:Truyền dữ liệu từ yêu cầu jquery ajax đến dịch vụ wcf không thực hiện được quá trình deserialization?

{"ExceptionDetail":{"HelpLink":null,"InnerException":null,"Message":"The token '\"' was expected but found '''.","StackTrace":" at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)\u000d\u000a at System.Xml.XmlExceptionHelper.ThrowTokenExpected(XmlDictionaryReader reader, String expected, Char found)\u000d\u000a at System.Runtime.Serialization.Json.XmlJsonReader.ParseStartElement()\u000d\u000a at System.Runtime.Serialization.Json.XmlJsonReader.Read()\u000d\u000a at System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore(XmlDictionaryReader reader, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)","Type":"System.Xml.XmlException"},"ExceptionType":"System.Xml.XmlException","Message":"The token '\"' was expected but found '''.","StackTrace":" at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)\u000d\u000a at System.Xml.XmlExceptionHelper.ThrowTokenExpected(XmlDictionaryReader reader, String expected, Char found)\u000d\u000a at System.Runtime.Serialization.Json.XmlJsonReader.ParseStartElement()\u000d\u000a at System.Runtime.Serialization.Json.XmlJsonReader.Read()\u000d\u000a at System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore(XmlDictionaryReader reader, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)"}

jquery của tôi trông như thế này, nhưng tôi đã cố gắng thay đổi dữ liệu thực tế mà tôi gửi như là một chuỗi json serialized (như bạn có thể nhìn thấy) đến một đối tượng json thuần túy với cùng kết quả buồn.

$.ajax({ 
    type: "POST", 
    contentType: "application/json; charset=utf-8", 
    url: "ajax/Statistics.svc/Get7DaysStatistics", 
    dataType: "json", 
    data: "{'customerId': '2'}", 
    timeout: 10000, 
    success: function(obj) { updateStatistics(obj.d); }, 
    error: function(xhr) { 
     if (xhr.responseText)   
      $("body").html(xhr.responseText); 
     else 
      alert('unknown error'); 
     return; 
    } 
}); 

Các dịch vụ WCF trông như thế này:

[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic"), OperationContract] 
    public string Get7DaysStatistics(string customerId) 
    { 
     Debug.WriteLine(customerId); 
     return "Test done"; 
    } 

Nó được đặt trong aa lớp với các thuộc tính sau:

[ServiceContract(Namespace = "")] 
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 

Tôi sẽ không liệt kê các cấu hình trong web.config để giữ cho thông điệp dài này "ngắn" nhưng tôi có thể đăng nó nếu ai đó nghĩ rằng họ có thể sử dụng nó - tôi chỉ muốn nhấn mạnh rằng tôi CÓ THỂ gọi một phương thức và nhận được kết quả - chuỗi hoặc thậm chí một đối tượng json tôi có thể đọc từ miễn là tôi làm N'T chuyển bất kỳ dữ liệu nào tới dịch vụ wcf.

Trả lời

32

Sử dụng dấu ngoặc kép thay vì dấu nháy đơn trong JSON bạn đang gửi đến dịch vụ. Đó là, sự thay đổi:

data: "{'customerId': '2'}", 

để

data: '{"customerId": "2"}', 

Tôi đã thử nghiệm này tại địa phương và điều này sửa chữa vấn đề.

Ngẫu nhiên, tôi đã sửa lỗi này bằng một phương thức mà tôi thường sử dụng khi gọi các dịch vụ ASMX và WCF bằng cách sử dụng các thư viện khác với các công cụ ASP.NET tích hợp sẵn. Tôi đã gọi dịch vụ bằng proxy của khách hàng được tạo bởi một số asp:ScriptReference và sau đó kiểm tra yêu cầu được gửi đến máy chủ bằng cách sử dụng trình thám thính HTTP (chẳng hạn như HttpFox cho FireFox) và so sánh yêu cầu với máy chủ được gửi bởi jQuery. Sau đó, bạn thường có thể nhanh chóng nhìn thấy những gì là khác nhau (và do đó có lẽ sai) với yêu cầu. Trong trường hợp này, rõ ràng là có sự khác biệt trong dữ liệu POST đang được gửi.

+1

Đó là hoang dã - tôi thực sự đã làm điều đó trước khi tôi đọc bài viết của bạn, nhưng nó không hoạt động. Sau đó, tôi figured có lẽ nếu tôi loại bỏ các thuộc tính WebInvoke davogones được đăng (và tôi thêm) nó có thể chỉ hoạt động và nó đã làm! –

+1

Sau một chút suy nghĩ (về lỗi của tôi) tôi nhận ra tôi chỉ hút vào tuần tự json: P Dữ liệu của tôi không được định dạng đúng json - đây không phải là phép thuật, json cần dấu ngoặc kép và không đơn. Javascript có thể không quan tâm nhưng json không, do đó, ofcourse nó sẽ giống như thế này. –

+0

Cảm ơn Daniel .................... PHEW. Hoàn toàn đúng khi bạn nói rằng JavaScript có thể không quan tâm, nhưng JSON thì có. Cảm ơn bạn. – user96403

0

Tôi nghĩ rằng hoạt động của bạn, bạn cần thuộc tính này:

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

Xem jQuery AJAX calls to a WCF REST Service để biết thêm.

+0

Tôi đã thêm thuộc tính nhưng tôi vẫn gặp phải lỗi - rất tiếc, lỗi hiện tại của tôi bị trống nên tôi không thể thấy vấn đề mới là gì. Tôi thậm chí đã thử thêm "RequestFormat = WebMessageFormat.Json" –

1

tôi đã làm một hàm trong JScript mà giải quyết vấn đề cho việc gửi dữ liệu thông qua POST đến một dịch vụ WCF ... theo các mã ...

chức năng formatJsonDataToWCFPost (d) {

var t = {}; 
var a = '{'; 
for (var j = 0; j < d.length; j++) { 
    var x = d[j]; 
    for (var i in x) { 
     if (x.hasOwnProperty(i)) { 
      var c = j + 1 == d.length ? '}' : ','; 
      a += ('"' + i + '":"' + x[i] + '"' + c); 
     } 
    } 
} 

return a; 

}

2

Tôi đã từng nghĩ rằng việc đăng bài là điều cần thiết cho chức năng đăng nhập tên người dùng và mật khẩu, do đó, đây là cách tôi mã hóa các thông số JSon tôi gửi đến dịch vụ web ...

Đây là hợp đồng Webservice ..

[ServiceContract] 
    public interface ILogonService 
    { 
    [OperationContract] 
    [WebInvoke(
     Method = "POST", 
     BodyStyle = WebMessageBodyStyle.WrappedRequest, 
     ResponseFormat = WebMessageFormat.Json 
    )] 
    string Logon(string un, string pw); 
    } 

Đây là JQuery (Lưu ý việc sử dụng "và" là rất quan trọng!)

$.ajax({ 
    type: 'POST', 
    url: "/LogonService.svc/Logon", 
    data: '{ "un": "' + $('#un').val() + '", "pw": "' + $('#pw').val() + '"}', 
    contentType: "application/json; charset=utf-8", 
    dataType: "json", 
    success: function (data) {  
    } 
}); 
Các vấn đề liên quan