将 jQuery 中的 WCF 作为 JSON 使用

Posted

技术标签:

【中文标题】将 jQuery 中的 WCF 作为 JSON 使用【英文标题】:Consuming WCF from jQuery as JSON 【发布时间】:2011-10-17 18:58:34 【问题描述】:

有合同:

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; 
        
    

及实施:

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

在 web.config 中配置为:

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

我正在尝试通过 jQuery 从页面调用 Foo:

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

但我收到 400 - Bad Request 错误消息 “服务器在处理请求时遇到错误。异常消息是'反序列化对象时出错键入 System.String。应从命名空间“”结束元素“根”。从命名空间找到元素“名称””

我错过了什么吗?

【问题讨论】:

【参考方案1】:

您的params 是对象,它形成 "name" : "someValue" JSON 字符串。如果您说邮件正文样式是Bare,我认为您的服务需要这样的内容:

[DataContract]
public class SomeDTO

    [DataMember(Name = "name")]
    public string Name  get; set; 

因此,您的操作应定义为:

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

如果您希望当前代码正常工作,您应该将其更改为:

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

【讨论】:

我认为 Bare 和 DTO 是最佳实践?【参考方案2】:

我遇到了同样的问题。设置后 BodyStyle=WebMessageBodyStyle.Wrapped 解决了。

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

【讨论】:

Ladislav Mrnka 的建议是一种解决方法。但是 BodyStyle=WebMessageBodyStyle.Wrapped 是一个正确的解决方法【参考方案3】:

尝试设置BodyStyle=WebMessageBodyStyle.Wrapped

source

【讨论】:

【参考方案4】:

BodyStyle = WebMessageBodyStyle.WrappedRequest 如果您从提琴手或其他休息客户端请求,则对我有用 但如果你从 HTTPWebResponse 请求,Bare 就可以了

【讨论】:

以上是关于将 jQuery 中的 WCF 作为 JSON 使用的主要内容,如果未能解决你的问题,请参考以下文章

JSON 中基于 WCF REST 的响应的 JQUERY AJAX

jQuery - 使用 ajax 调用将 JSON 发送到 WCF 服务为空

将 JSON 数据从 JQuery 发送到 WCF REST 方法时出现问题

使用日期将 JQuery JSON 发送到 WCF REST

WCF POST 通过 JQuery。如何在 JSON 中发送数组?

使 ASP.NET WCF 将字典转换为 JSON,省略“键”和“值”标签