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


Playing around with silverlight on the web

clock May 26, 2009 16:07 by author tim

I had a bit a free time last week to play around with silverlight.  A couple of observations based on my 2 hours of playtime are:

1.  Silverlight/XAML in general feel alot like Adobe FLEX 
2.  coding for silverlight won't make sense until you understand it is a CLIENT side technology so you will need to work with data connectivity just like you would with Javascript (making a AJAX call) or FLEX/FLASH making a call to a webservice.  So since silverlight runs on the client side it doesn't have access to a SQL datasource (for security reasons).....you'll need to reference a service (see notes and code below).

Getting Data into a grid.  Below is a little snippet from the codebehind of a xaml page. 

The process i went through was

1.  created a WCF service  library (don't forget about the clientaccesspolicy.xml..what a pain)
2.  Referenced Library in Silverlight project
3.  OnLoad call the webservice method that returns a collection (in my case) "GetIssuesAsync()"
4.  Add a method that captures the webservice methods "Complete" event

public Page() 
{    
   InitializeComponent(); 
   Loaded += new RoutedEventHandler(Page_Loaded); 
} 
 
void Page_Loaded(object sender, RoutedEventArgs e) 
{    
   
   ServiceReference1.Service1Client webservice = new Service1Client(); 
   webservice.GetIssuesCompleted += new EventHandler<GetIssuesCompletedEventArgs>(webservice_GetIssuesCompleted);
   webservice.GetIssuesAsync(); 
} 
 
  
 
public void webservice_GetIssuesCompleted(object sender, GetIssuesCompletedEventArgs e) 
{ 
 
    dataGrid1.ItemsSource = e.Result; 
} 

Currently rated 5.0 by 1 people

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


Mapping types using ConvertAll ASP.Net 2.0

clock March 24, 2009 11:41 by author tim

A quick way to convert a generic list of one type to another (more for documentation)

List<Merchant> merchant = new List<Merchant>(); 
List<MerchantDTO> mdtos = merchant.ConvertAll<MerchantDTO>(new Converter<Merchant, MerchantDTO>( 
 
     delegate(Merchant m){      
      
      MerchantDTO mdto = new MerchantDTO();
      mdto.ID = m.ID;
      mdto.Name = m.Name; return mdto; 
  
 
      } 
 
)); 

Currently rated 5.0 by 1 people

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


Ext JS C# 3.5 JSON Helper Class: Object to JSON and JSON to Object

clock July 1, 2008 09:40 by author tim

With Microsofts new extension methods it makes it easy to create helper methods that take care of the JSON grunt work.  Listed below is an example of how to implement JSON extension methods.

Helper Class

using System.IO;
using System.Text;
using System.Collections;
using System.Runtime.Serialization.Json;
    
public static class ExtJsJsonHelper 
    {
        public static string ToExtJsJson(this IEnumerable collection, string rootName)
        {
         DataContractJsonSerializer serializer = new DataContractJsonSerializer(collection.GetType());
            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, collection);
                StringBuilder sb = new StringBuilder();
                sb.Append("{" + rootName + ":");
                sb.Append(Encoding.Default.GetString(ms.ToArray()));
                sb.Append("}");
                return sb.ToString();
            }
        }
        public static string ToExtJsJsonItem(this object item, string rootName)
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(item.GetType());
            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, item);
                StringBuilder sb = new StringBuilder();
                sb.Append("{success:true," + rootName + ":");
                sb.Append(Encoding.Default.GetString(ms.ToArray()));
                sb.Append("}");
                return sb.ToString();
            }
        }
        public static string ToExtJsJsonItem(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 string ToExtJsJson(this IEnumerable collection, string rootName, string countName)
        {
 
            ICollection c = (ICollection)collection;
 
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(c.GetType());
            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, c);
                StringBuilder sb = new StringBuilder();
                sb.Append("{" + countName + ":" + c.Count + ",");
                sb.Append(rootName + ":");
                sb.Append(Encoding.Default.GetString(ms.ToArray()));
                sb.Append("}");
                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;
        }
  
 
    }

Example of Object to JSON string

    public class GetAllCampaignsCommand : ICampaignServiceCommand
    {    
 
        public string Execute(NameValueCollection nameValueCollection)
        {
 
            ICampaignRepository repository=new CampaignDatabaseDataContext();
 
            List<Campaign> campaigns = repository.GetCampaigns();
            List<CampaignDTO> campaignsdto= new List<CampaignDTO>();
 
            foreach (Campaign c in campaigns)
            {
                campaignsdto.Add(c.ToDTO());
            }
 
            return  campaignsdto.ToExtJsJson("items", "totalCount");
        }
 
    }

 

Example of JSON string to Object

        public string Execute(NameValueCollection nameValueCollection)
        {
            string prospectjson = nameValueCollection["prospect"] ?? "";
 
            if (prospectjson.Length == 0)
            {
                throw new ArgumentException("Prospect data is required.");
            }
 
            ProspectDTO prospectdto = prospectjson.FromJsonTo<ProspectDTO>();
 
            int prospectid= CampaignController.AddProspect(prospectdto);
 
            return "success";
        }
 
    

Currently rated 4.5 by 4 people

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


Team Foundation Server and Continuous Integration

clock June 27, 2008 07:57 by author tim

Continuous Integration is a software development practice where members of a team integrate their work frequently; usually each person integrates at least daily - leading to multiple integrations per day. - Martin Fowler 

Martin Fowler’s article “Continuous Integration” listed several key practices that make up “Effective CI”. Here is a quick overview of how Team Foundation Server combined with Automaton can help implement some of these practices.

Key Practices identified by Fowler:

1. Maintain a Single Source Repository

2. Automate the Build

3. Everyone Commits Every Day

4.  Automate Deployment

 

Side Note:

Best Practices for setting up projects in Team Foundation Server

Taken from TFS Best Practices Guide

- Decide on team project structure
- Understand the culture and requirements for each of the teams
- Map requirements to our logical and physical guidance and create first draft of the logical
- Make necessary modifications to the structure (baseless merge where appropriate)
- Finalize logical and physical diagrams
- Follow release scenarios on these diagrams
- Create Team Project and physical version control structure (import any existing code)
- Create best practices and provide training
- Learn from experiences, customize the branch structure, and make it yours

1: Maintain a Single Source Repository

Team Foundation Server’s source control service provide branching and merging capabilities that help to ensure a centralized and controlled repository for all items needed to build the application successfully. Figure 2 details the specific folder structure and branching strategy used at a former company.

clip_image002

Figure 2 Source Control Structure

2: Automate the Build

A build process helps ensures that the code will compile independently from the developer’s workspace and standardizes configuration across the promotion process. Oftentimes developers will forget to check in critical files and then deploy from their computer. After the initial release everything may run fine but when the next developer checks out the source to make modifications they soon discover that the application no longer builds.

  • Determine promotion process needed for project (dev, staging, release)
  • Create a Build Type on team foundation server for each promotion type
  • If .Net is used configure build types for each solution
  • If a website is used configure web deployment project for each build type (this is where dev config files and production config files are specified)
  • If the application is an access or .asp application then configure .bat files or other script files. These will execute during the build process (this may run testing against code or verify that certain dll’s are registered)

3: Everyone Commits Every Day

Checking in code is done as soon as a new task is completed. If a task is carried over to the next day the item is “shelved”.

clip_image002[4]

Figure 3 Check-In - Build - Deploy

4: Automate Deployment

note: since the time I had documented this we have upgraded to TFS 2008 which has made CI simple and eliminated the need for Automaton. 

At a previous company one of our goals was to have an integration process that allowed us to provide updates to an application as real-time as possible. The deployment process was setup to build and deploy to the appropriate server as soon as a developer checks-in code. This allowed us to push out new features and bug fixes without having to worry about the manual process of copy files and testing to make sure the appropriate references have been set.

  • for web projects this involves configuring the web deployment project for the solution to deploy the compiled source to the correct server for each build type
  • for non .net solutions like access or asp this may involve creating bat files that are executed by the build server to copy the necessary files to each server

The key to making the deployment “Real-Time” is to either write custom code that hooks into Team Foundations Servers “Check-in” event or use a third party application that does that for you. In our case we use Automaton.

Automaton is configured to run the specified build configuration when code is checked in. You can also monitor the build status or view the history of the builds using their web interface.

Web deployment projects can be a useful addition to your solution as well. Staging and release configurations can be controlled during the automated deployment process (i.e. web.config file that has dev, staging, and production settings).

clip_image004

Figure 4 third party TFS add on

Credits:

Martin Fowler http://www.martinfowler.com/articles/continuousIntegration.html

Article Featured on Blog Catalog

Currently rated 5.0 by 1 people

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


ASP.NET MVC Preview 3 and fairy dust

clock June 18, 2008 14:38 by author tim

Trying to find the MVC framework’s place in the development world view of Web 2.0 and EXTJS (or any other JavaScript library) I am reminded of Microsoft's 2000 PDC unveiling of ASP.NET and the announcement of the fairy dust of integration, web services (you just need a sprinkle). 

When ASP.NET was introduced developers knew that things were changing (especially if you came from a classic asp world).  You just weren’t quite sure what you needed to do to make these changes work for you.  I remember the first two years of ASP.NET as a blur of failed projects; trying to find reason to implement the fairy dust of web service based architects (soon to tagged as SOA).   Working with the MVC framework gives me a similar feeling…….I know it’s a needed change but I’m not if Microsoft’s has made the reason we need the MVC framework very clear.

While MVC is a small framework and tiny in comparison to the changes brought on by the Post-Classic ASP cold war, it does hint at what’s to come.  The more I work with Javascript libraries and “Service” based ASP.NET projects the less of a role I see ASP.NET playing in the rendering of UI Controls. That is where MVC pays its dividends,  taking care of the server side architect and letting client based scripting take care of the UI Magic.

MVC plugged into the traditional way of building ASP.NET makes little sense (the least sense for the drag and droppers).  But, if web apps continue to evolve into more Rich State filled Balls of AJAX wonder, MVC may be the next fairy dust.

Here is a link to Alan Lok’s excellent look at MVC and EXTJS: Ext JS and ASP.NET MVC


Be the first to rate this post

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


LINQ to SQL Saving Nested/Children Objects (reference only)

clock June 18, 2008 13:04 by author tim

 

public partial class CommunityPromotion
{ 
     public bool IsNew
     { 
          get
          { 

               return this.ID <1; 
          } 
     } 

     public bool isDeleted { get; set; } 
} 


//create a partial class for the database context and extend an interface that defines custom methods 


public partial class DatabaseDataContext : IPromotionRepository
{ 

     public void Save(Promotion promotion)
     {
          if (promotion.ID < 1)  // if its a new promotion just insert it
          {
               this.Promotions.InsertOnSubmit(promotion); 
          }
          else  // if its an update to a promotion... check to see if any of the nested objects are marked as new or for delete
          { 

            //  this grabs all of the promotion objects that are new and inserts them 


               this.CommunityPromotions.InsertAllOnSubmit(promotion.CommunityPromotions.Where(a => .IsNew));
               this.CommunityPromotions.DeleteAllOnSubmit(promotion.CommunityPromotions.Where(a => a.isDeleted));
  
          } 

          this.SubmitChanges(); 
     } 

} 

Currently rated 5.0 by 1 people

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


Grabbing single entity using LINQ to SQL

clock June 4, 2008 08:52 by author tim

 

Order orders = (from o in Orders where o.ID == id select o).First(); 

Be the first to rate this post

  • Currently 0/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