从jQuery使用WCF作为JSON

时间:2023-01-18 09:49:29

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 Request error 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 - 错误请求错误消息“服务器遇到处理请求的错误。异常消息是'反序列化System.String类型的对象时出错。结束元素'root'来自命名空间' 'expected。从命名空间中找到元素'name'。

Am I missing something?

我错过了什么吗?

4 个解决方案

#1


15  

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

你的参数是对象,它形成{“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);

#2


6  

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

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

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

#3


4  

Try setting BodyStyle=WebMessageBodyStyle.Wrapped

尝试设置BodyStyle = WebMessageBodyStyle.Wrapped

source

资源

#4


0  

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将工作

#1


15  

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

你的参数是对象,它形成{“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);

#2


6  

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

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

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

#3


4  

Try setting BodyStyle=WebMessageBodyStyle.Wrapped

尝试设置BodyStyle = WebMessageBodyStyle.Wrapped

source

资源

#4


0  

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将工作