Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Consuming WCF from jQuery as JSON

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:

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

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

Am I missing something?

like image 404
Bullines Avatar asked Aug 01 '11 21:08

Bullines


2 Answers

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:

[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);
like image 66
Ladislav Mrnka Avatar answered Oct 01 '22 08:10

Ladislav Mrnka


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

[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
like image 37
Arun Raj Avatar answered Oct 01 '22 07:10

Arun Raj