Mark Brittingham
Mark Brittingham

Reputation: 28865

Why am I not able to pass a JSON object to a WCF web service?

I built a fairly complex app using the older "ASMX" web service implementation and I am migrating to WCF. There is one thing that is just driving me crazy - it should be easy but my AJAX calls error out no matter how I try to structure this call. This worked fine with ASMX calls but not with WCF.

Here is the AJAX call:

        var ProfileData = new Object();
        ProfileData.SUID = SUID;
        ProfileData.FirstName = $("#FirstName").val();
        ProfileData.LastName = $("#LastName").val();
        ProfileData.Birthdate = new Date($("#Birthdate").val());
        var DTO = {'ProfileData': ProfileData };

        $.ajax({
            type: "POST",
            url: "AllianceService.svc/SaveBasicProfile",
            data: JSON.stringify(DTO),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (msg) {
                    UpdateTips($("#BasicProfileValidate"), "Success! Your data has been updated.");
                }
            },
            error: function (xhr, ajaxOptions, thrownError, request, error) {
                alert('Error Saving Basic Profile Data');
            }
        });

Here is the declaration of the type on the C# / Server side:

[DataContract]
public class BasicFolderData
{
    [DataMember]
    public string SUID { get; set; }
    [DataMember]
    public string FirstName { get; set; }
    [DataMember]
    public string LastName { get; set; }
    [DataMember]
    public DateTime Birthdate { get; set; }
}

And here is the definition of the service:

    [OperationContract]
    public int SaveBasicProfile(BasicFolderData ProfileData)
    {
         ... do stuff
    }

Now, if I break out all of the datamembers and use them as parameters, I can get this to work with a simple

    data: JSON.stringify(ProfileData)

But the object is actually much longer than this and I'd like to know how to pass objects.

Also, I have tried:

    data: JSON.stringify({"ProfileData": ProfileData }),

and

    data: JSON.stringify('{"ProfileData":' + ProfileData + '}'),

and

    data: '{"ProfileData":' + JSON.stringify(ProfileData)  + '}',

but all to no avail...I get the error message on all of them.

If I use:

    data: JSON.stringify(ProfileData), 

then, oddly enough, the request makes it to the server but the ProfileData parameter is null. I suspect that the problem is my datacontract but don't know where to start. Also, I have a lot of functions with scalar parameters that work just fine - it is only when I attempt to pass objects that I fail. Any help would be greatly appreciated!!

Following DonAndre's suggestion, I have found that simply changing the parameter to a scalar type will make the call succeed. However, the parameter is always null.

Upvotes: 2

Views: 888

Answers (2)

Mark Brittingham
Mark Brittingham

Reputation: 28865

Ok - the problem was trivial: the "BasicFolderClass" had a DateTime field (Birthdate) in it.

When JSON.stringify is called on the DTO object, it turns the DateTime field in the javascript side into a string before sending it up. The mismatch on that field between the JSON string being presented and the DateTime being expected is what led to the error.

Upvotes: 1

Andreas
Andreas

Reputation: 6465

WCF wraps the JSON with a d if you have enableWebScript set to true in your config on the server. Take a look here: JsonConvert.DeserializeObject and "d" wrapper in WCF

Upvotes: 1

Related Questions