从 jQuery 使用 WCF 作为 JSON

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6904609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 21:31:48  来源:igfitidea点击:

Consuming WCF from jQuery as JSON

jquerywcfjson.net-4.0

提问by Bullines

With a contract:

有合同:

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

And implementation:

和实施:

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 in the web.config as:

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

I'm trying to call Foo from a page via jQuery:

我正在尝试通过 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>

But I'm getting a 400 - Bad Requesterror with the message "The server encountered an error processing the request. The exception message is 'There was an error deserializing the object of type System.String. End element 'root' from namespace '' expected. Found element 'name' from namespace".

但是我收到一个400 - Bad Request错误,消息为“服务器在处理请求时遇到错误。异常消息是‘反序列化 System.String 类型的对象时出现错误。来自命名空间的结束元素‘root’” ' 预期。从命名空间中找到元素 'name'"

Am I missing something?

我错过了什么吗?

回答by Ladislav Mrnka

Your paramsis object and it forms { "name" : "someValue" }JSON string. If you say that message body style is BareI think your service expects something like this:

params是对象,它形成{ "name" : "someValue" }JSON 字符串。如果您说消息正文样式是Bare我认为您的服务需要这样的东西:

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

And because of that your operation should be defined defined as:

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

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

If you want your current code to work you should probably change it to:

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

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

回答by Arun Raj

i got the same issue. after setting BodyStyle=WebMessageBodyStyle.Wrappedit solved.

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

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

回答by Jay

Try setting BodyStyle=WebMessageBodyStyle.Wrapped

尝试设置 BodyStyle=WebMessageBodyStyle.Wrapped

source

来源

回答by waqas jawaid

BodyStyle = WebMessageBodyStyle.WrappedRequest worked for me if you are requesting from fiddler or other rest clients but if you are requesting from HTTPWebResponse Bare would be working

BodyStyle = WebMessageBodyStyle.WrappedRequest 如果您从 fiddler 或其他休息客户端请求,但如果您从 HTTPWebResponse 请求 Bare 将工作