Practical ASP.NET

Integrating AJAX and a Client-Side Grid in ASP.NET MVC

Peter completes his series on integrating AJAX and a client-side control by implementing it in ASP.NET MVC. And he draws some conclusions on client-side development in ASP.NET, ASP.NET MVC, and in the world at large.

This column completes a discussion from in an earlier column where I suggested that if, in ASP.NET MVC, you want a grid, you should use a client-side grid that interacts with Web services. In that column and the following ones, I've implemented the ExtJs grid in "traditional" ASP.NET with asmx files and with WCF services (See JavaScript Controls with WCF and ASP.NET). To swap those technologies in and out, I had to make minor changes to my client-side code (one line) and server-side code (integrating with WCF).

In porting the application to ASP.NET MVC, many of the changes are mechanical. After creating an ASP.NET MVC application, I recreated my Entity Framework model (still the easiest way to generate my business objects) for the Northwind database. I put the class file with my data transfer object (CustomerDTO) in the Models folder. I then added the ExtJs files to my application, putting whole of the ExtJs resources and adapter folders to my project's Contents and Scripts folders. I also included the base jQuery library and put my own code in a script file:

<link href="../../Content/ExtJs/resources/css/ext-all.css" 
      rel="stylesheet" type="text/css" />
<script src="../../Scripts/ExtJs/adapter/ext/ext-base.js"
        type="text/javascript"></script>
<script src="../../Scripts/ExtJs/ext-all.js"
        type="text/javascript"></script>
<script src="../../Scripts/jquery-1.4.1.min.js" 
 type="text/javascript"></script>
<script src="../../Scripts/Index.js"
 type="text/javascript"></script>

I added my two buttons to the form on the Index.aspx page called from HomeController. So far, no real changes other than using jQuery to attach my events to my buttons:

$(function () {
	$("#btnGetCustomers").bind("click", function (e) {
		return getCustomers();
	});
	$("#btnSaveCustomers").bind("click", function (e) {
		return saveCustomers();
	});

	}
);

Those changes were all discretionary. But my Web service methods, rather than going in separate files, are now part of the HomeController that handles my view. Changes were definitely required here to make it work. For instance, in the method that returned customer object, I had to explicitly specify the root for my array of JSON object (before, this just defaulted to "d"):

Public Function GetCustomers() As ActionResult

  Dim nw As New northwndEntities
  Dim res = New With {
            .d = From cust As Customer
                  In nw.Customers
                  Select New CustomerDTO With {
                      .ContactName = cust.ContactName, 
                      .CustomerId = cust.CustomerID}
                   }
  Return Json(res)

End Function

The method that accepts the JSON objects coming back from the client needed more extensive changes -- I couldn't get the results returned in a parameter to the method. Instead, I had to assemble the JSON string from the Request object's InputStream, strip out some unnecessary characters and then use the JSON serializer to convert the result into my data transfer object (the update code didn't change). I turned the conversion code into a generic method that I can use in any subsequent application:

Public Function UpdateCustomer(ByVal d As Object) As ActionResult
   Using nw As New northwndEntities
        Dim cDTOs As CustomerDTO()
       cDTOs = ConvertJSON2DotNet(Of CustomerDTO())()
        For Each cDTO As CustomerDTO In cDTOs
            UpdateACustomer(nw, cDTO)
       Next
        nw.SaveChanges()
   End Using
   Return View("Index")
End Function

Function ConvertJSON2DotNet(Of T)() As T
   Dim Json As New StringBuilder
   For ing As Integer = 0 To Request.ContentLength - 1
     Json.Append(Convert.ToChar(Request.InputStream.ReadByte()))
   Next
   Dim ser As New System.Web.Script.Serialization.JavaScriptSerializer()
   Dim js As New JavaScriptSerializer
   Json.Remove(Request.ContentLength - 1, 1)
   Json.Remove(0, 5)
   Return js.Deserialize(Of T)(Json.ToString)
End Function

I then had to change the URLs that my client-side code used to point to my Web service methods:

proxyCustomer = new Ext.data.HttpProxy({
        api: {
            read: "/Home/GetCustomers",
            update: "/Home/UpdateCustomer"
        },
        method: "POST"
    });

And with those changes, my grid displayed customers and let me do updates. The download for this week's column has the working versions of all three projects: The original using ASMX files, the second iteration using WCF, and this version using ASP.NET MVC.

One of the claims for ASP.NET MVC is that it's a better platform for JavaScript than "traditional" ASP.NET. Personally, I'm not getting that. As far as writing or debugging JavaScript code goes, I find ASP.NET and ASP.NET MVC virtually interchangeable. For this application, it was easier to use WCF than MVC Action methods. I'm not suggesting that ASP.NET MVC isn't a great technology -- I am saying that I don't see the JavaScript benefits, compared to the other options. And I realize that this one application does not a development platform make.

On the other hand, I remain excited about the power of the JavaScript and Web services paradigm. There's no doubt that using a client-side grid is more work for the developer than using a GridView and, thanks to the nature of JavaScript, harder to debug (misspell the name of a property? Not a problem: JavaScript just adds the property). We also desperately need a JavaScript MVC programming infrastructure on the client where we're creating applications whose architecture we'd sneer at on the server.

But, for me, the benefits of the AJAX paradigm in terms of responsiveness, scalability, reusability, and integration of services far out way those costs.

Anyway, that's enough client-side programming for a couple of columns, at least. For the next few columns "real" ASP.NET stuff: the listbox, Crystal Reports vs. SSRS, and back to encrypting the web.config. Then it's client-side programming with the new jQuery additions.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events