Thursday, March 28, 2013

jQuery Ajax POST to REST WCF Returns a Bad (Status 400) Request

Problem,


Note: I have recently found out that you can do this much easier with the Microsoft Web API framework. This is a configuration hell and I will not recommend it.

I recently have started to implement a RESTful interface using the WCF in ASP.NET. The advantage of using the WCF is that on the C# side (can be a VB or even F#), the coding can be done in C# without much worries, and we can take advantage of the built-in  (de)serialization in JSON format, which is very common dealing with JavaScript.

In my situation, the client side is a JQuery running in a standard web browser. And that's where the problem begun.

A "GET" method worked quite easily, but the POST method did not work initially, and it is a rather complex issue especially with Web.Config endpoint behaviors and such.

Some Points to Check

First, most examples on the web, including the ones in the JQuery document pages, are not always correct for encoding a JSON data. The following example is the correct one that worked. All I needed was a pair of single quote surrounding the JSON data itself, and that was the key.

var p = '{ "c" : "Hello", "dt" : "2013-03-27" }';

Above structure reflects this in C#

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

        [DataMember (Name="dt")]
        public string dt
        {
            get;
            set;
        }

Second, it looks like you need to use the $.ajax interface, instead of $.post because WCF side needs the content type of application/json and charset of utf-8 and decides to de-serialize the data. Without this information you will very likely get the Error status 400.  So it is essential that JSON ContentType must be specified when uploading the POST data.

You can use the following calling framework when POSTing a JSON object to WCF from your JavaScript.

Since the $.post does not (seem to) allow the explicit contentType specification, this is the reason you need to go to $.ajax call.

              var x = $.ajax(
                {
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    url: url,
                    data: p,
                    dataType: "json",
                    success: asuccess
                }       );

Finally, there are many things you need to modify your Web.Config but there are a lot of posts about this on StackOverflow or places of that nature so I will let you figure that out.

These are probably very novice errors, nevertheless, there are a lot of posts on this on the network, so I am sure this information will help someone down the line.

P.S.: It's JSON and not JaSON!

Wednesday, March 13, 2013

LinqDataSource Bound Grid View and RowDataBound Handling

Scenario

You have bound a LinqDataSource to DataGridView.

Now you want to dynamically modify the contents of grids using RawDataBound event based on the row data, for example flag a field as RED when there is an overdue account, but you do not know how to get to the data contained in Row.DataItem

You will quickly find that DataItem is a member of DynamicClass for which there is no public property to methods to get to the data. You will also find that your debugger can display the information, and it just a row from a LINQ select statement.

Solution

A very small amount of Reflection is needed to do this work. Suppose that you had a column in the table in the LinqDataSource with the name of "CustomerGuidKey". Here is how to get at it.

   protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        var item = e.Row.DataItem;
        if (item == null) return;
        var t = item.GetType();
        PropertyInfo p = t.GetProperty("CustomerGuidKey");
        var v = (Guid) p.GetValue(item, null);
.....

Be sure to include the namespace "System.Reflection" in your code.