AgileRock.com

agile development, asp.net,C#, JSON

JQuery JQGrid and ASP.Net 3.5 C# JSON Handler

clock June 26, 2009 13:50 by author tim

I recently had a project that required a simple grid with the ability to add and edit records (your typical crud operations).  As with most of the stuff on my blog I thought it would make sense to document how the grid functions…..should I ever need it again.

image

I have also attached the project files below.

Download: Source

The core functionality of the grid is provided in the JavaScript below.  from app.grid.js:

var lastsel2;
//you can pass in parameters if needed
var id = $(document).getUrlParam("id");
var type = $(document).getUrlParam("type");
jQuery("#grid").jqGrid({
    datatype: "local",
    colNames: ['ContactID', 'FirstName', 'LastName', 'Address1', 'Address2', 'City', 'State', 'ZipCode', 'Phone', 'Fax', 'Email', 'ContactType'],
    colModel: [
		{ index: 'ContactID', name: 'ContactID', hidden: true, width: 40, sortable: true, align: 'center', editable: true },
		{ index: 'FirstName', name: 'FirstName', width: 80, sortable: true, align: 'left', editable: true },
		{ index: 'LastName', name: 'LastName', width: 80, sortable: true, align: 'left', editable: true },
		{ index: 'Address1', name: 'Address1', width: 80, sortable: true, align: 'left', editable: true },
		{ index: 'Address2', name: 'Address2', width: 80, sortable: true, align: 'left', editable: true },
		{ index: 'City', name: 'City', width: 80, sortable: true, align: 'left', editable: true },
		{ index: 'State', name: 'State', width: 50, sortable: true, align: 'left', editable: true },
		{ index: 'ZipCode', name: 'ZipCode', width: 50, sortable: true, align: 'left', editable: true },
		{ index: 'Phone', name: 'Phone', width: 80, sortable: true, align: 'left', editable: true },
		{ index: 'Fax', name: 'Fax', width: 80, sortable: true, align: 'left', editable: true },
		{ index: 'Email', name: 'Email', width: 80, sortable: true, align: 'left', editable: true },
		{ index: 'ContactTypeName', name: 'ContactTypeName', width: 80, sortable: true, align: 'left', editable: true, edittype: "select" }
		],
    rowNum: 20,
    rowList: [10, 20, 30],
    imgpath: 'themes/steel/images',
    sortname: 'ID',
    viewrecords: true,
    sortorder: "desc",
    editurl: 'datahandler.ashx?method=updatecontact&insertid=' + id + "&contactupdatetype=" + type,
    caption: 'contacts',
    onSelectRow: function(id) {
        if (id && id !== lastsel2) {
            jQuery('#grid').restoreRow(lastsel2);
            jQuery('#grid').editRow(id, true);
            lastsel2 = id;
        }
    }
});
$("#badata").click(function() {
    jQuery("#grid").editGridRow("new", {
        height: 300,
        reloadAfterSubmit: false,
        closeAfterAdd: true,
        afterComplete: function() { loaddata() }
    });
});
var contacttypes = {
    1: "Admin",
    2: "Manager",
    4: "Building Manager",
    6: "Location Manager",
    9: "Other"
}
loaddata();
function loaddata() {
    $("#grid").clearGridData();
    jQuery(function($) {
        $.ajax({
            type: "POST",
            url: "datahandler.ashx",
            data: "method=getcontacts&id=" + id + "&contactedittype=" + type,
            success: function(jsondata) {
                if (jsondata == undefined) { return; }                
                var data = JSON.decode(jsondata)
                for (var i = 0; i < data.length; i++) {
                    jQuery("#grid").addRowData(data[i].ID, data[i]);
                }
                $("#grid").setColProp('ContactTypeName', { editoptions: { value: contacttypes} });
            }
        });
        var b = $(document).getUrlParam("test");
    })
}

The grid calls a .ashx handler file that returns the appropriate json data.  On the server side reside the handler file and the command files.

datahandler.ashx:

public class datahandler : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        string responseText = "";
        string method = context.Request.Params["method"] ?? "";
        ICommand command = CommandFactory.Create(method);
        if (command != null)
            responseText = command.Execute(context.Request.Params);
        
        
        context.Response.Write(responseText);
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }
}

The handler uses the CommandFactory to build the appropriate command based on the “method” parameter that is passed in.  The execute method on the command does all the grunt work.   For this demo the “GetContacts” create test data objects but you can easily insert your own data access functionality. 

CommandFactory:

    public class CommandFactory
    {
        public static ICommand Create(string commandName)
        {
            switch (commandName.Trim().ToLower())
            {
                case "getcontacts":
                    return new GetContacts();
                case "updatecontact":
                    return new UpdateContact();
                default:
                    return null;
            }
        }
    }

The server side builds the JSON using helper methods that leverage the functionality of the .Net’s built in DataContractJsonSerializer

JsonHelper.cs

public static class JsonHelper
{
    public static string ToJsonItem(this object item)
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(item.GetType());
        using (MemoryStream ms = new MemoryStream())
        {
            serializer.WriteObject(ms, item);
            StringBuilder sb = new StringBuilder();
            sb.Append(Encoding.Default.GetString(ms.ToArray())); return sb.ToString();
        }
    }
    public static T FromJsonTo<T>(this string jsonString)
    {
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
        MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString));
        T jsonObject = (T)ser.ReadObject(ms);
        return jsonObject;
    }
}

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Testing Live Writers code Plug in

clock June 24, 2009 08:40 by author tim

 

For those of you blogging with BlogEngine.Net I highly recommend Windows Live Writer.  Its “Code” formatting plug-in helps with the nightmare of trying to format or display code snippets.  Here is example

Without the code plugin

public class AddressValidationProviderFactory
{
    public static IAddressValidationProvider Create()
    {

        return new PurolatorAddressValidationProvider();

    }
}

 

With code plugin

   1:      public class AddressValidationProviderFactory
   2:      {
   3:          public static IAddressValidationProvider Create()
   4:          {
   5:   
   6:              return new PurolatorAddressValidationProvider();
   7:   
   8:          }
   9:      }

Currently rated 4.0 by 2 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Dallas TechFest 2009 Review

clock June 22, 2009 12:06 by author tim

Overall the conference was just OK.  For the cost (even if you got suckered into the $75 fee) I don't have alot of room to complain but here is a short review of my experience: 

The Good

 1.  "Some" Good presenters.  I specifically liked Caleb Jenkins presentation on DI.  Here are a few items I wrote down during his presentation:

  • Spark Energy Drink
  • Unity "CodePlex"
  • DevelopingUX.com

The Bad 

1.  Lack of vendors/sponsors.  I think there were maybe 3. I like free stuff.

2.  ...Um seemed a little chaotic during registration.

3.  Stick on badges? Combined with no free lunches...most nametags were ripped or missing after going out for lunch.

4.  The silverlight track was a little weak.  It would have been nice to have more advanced topics instead of assuming everybody was new to silverlight.

The Ugly

1.  Teasing us with free coffee and breakfast was just wrong (the bankruptcy conference had it).  I know coffee was offered after the first session but c'mon.

2.  Parking was bad.

 

Currently rated 3.5 by 2 people

  • Currently 3.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Search

Calendar

<<  March 2010  >>
SuMoTuWeThFrSa
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

Archive

Tags

Categories


Blogroll

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

Sign in