jordan.baucke
jordan.baucke

Reputation: 4328

Making correct JSON Post in C# to MVC 2 REST webservice

I've got my MVC2 RESTFul webservice all set to accept JSON and return some using an example I found here

Good stuff, this example works just fine posting the JSON via jQuery, and handling the JSON response:

        $(function () {
        $("#personCreate").click(function () {
            var person = getPerson();

            // poor man's validation
            if (person == null) {
                alert("Specify a name please!");
                return;
            }

            var json = $.toJSON(person);

            $.ajax({
                url: '/home/save',
                type: 'POST',
                dataType: 'json',
                data: json,
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    // get the result and do some magic with it
                    var message = data.Message;
                    $("#resultMessage").html(message);
                }
            });
        });
    });

However, I need to call my webservice automatically (one server calling another, no client-side jQUERY here). So I'm doing this all in C#:

  private static void MakeJSONServiceCall(PersonInputModel person)
    {
        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ServiceUrl);
            request.Method = "POST";
            request.ContentType = "application/json; charset:utf-8";
            DataContractJsonSerializer ser = new DataContractJsonSerializer(person.GetType());
            MemoryStream ms = new MemoryStream();
            ser.WriteObject(ms, person);
            String json = Encoding.UTF8.GetString(ms.ToArray());
            StreamWriter writer = new StreamWriter(request.GetRequestStream());
            writer.Write(json);
            writer.Close();
        }
        catch (Exception e)
        {

        }
    }

Excep, when the DataContractJsonSerializer serializes my object I get some garbage with a bunch of escaped tags:

"{\"<Age>k__BackingField\":24,\"<Name>k__BackingField\":\"Jordan\"}"

Doesn't look like good JSON to me!?

Fixed:

"{\"Age\":24,\"Name\":\"Jordan\"}"

The class, is properly decordated:

[Serializable]
public class PersonInputModel {
    public string Name { get; set; }
    public int Age { get; set; }
}

Fixed:

[DataContract]
public class PersonInputModel {
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public int Age { get; set; }
}

And than when I run the webservice, and put in the URL it never gets hit even as I step through this code.

What am I missing?

Thanks!


On closer examination using Fiddler, I'm not seeing a "POST" taking place at all as I step through:

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ServiceUrl); 
        request.Method = "POST"; 
        request.ContentType = "application/json; charset:utf-8"; 
        DataContractJsonSerializer ser = new DataContractJsonSerializer(person.GetType()); 
        MemoryStream ms = new MemoryStream(); 
        ser.WriteObject(ms, person); 
        String json = Encoding.UTF8.GetString(ms.ToArray()); 
        StreamWriter writer = new StreamWriter(request.GetRequestStream()); 
        writer.Write(json); 
        writer.Close(); 

Thoughts?

Upvotes: 1

Views: 6885

Answers (2)

jordan.baucke
jordan.baucke

Reputation: 4328

I've updated my code to use an IAsyncResult

Per the example here:

http://msdn.microsoft.com/en-us/library/system.net.webrequest.begingetrequeststream.aspx

This solution correctly hit the web service and read back the JSON result (I think my issue was my service returned JSON data on the result side of things and I wasn't waiting to read it back properly!

Thanks for the help!

Upvotes: 0

SLaks
SLaks

Reputation: 888047

You need to use the DataContract attributes:

[DataContract]
public class PersonInputModel {
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public int Age { get; set; }
}

Your existing code is serializing the class' compiler-generated backing fields, which have unexpected names.

Upvotes: 2

Related Questions