Tuesday, September 24, 2013

Using jQuery to Post Data to an ASP.Net Web Forms Web Method via Model Binding

Scenario

I recently ran into a situation where I needed to use AJAX to call back to a traditional ASP.Net Webform's web method in the code behind for a quick lookup. There was a large number of values that were directly related to a model I was using. So, I decided to do this via model binding similarly to how ASP.Net MVC utilizes this same binding techniques for the post data, to keep from having to do the parameter to model translation and save myself some typing.

As a personal preference, I like to use JavaScript Object Notation (JSON) to populate the data being submitted to the server. This is just a personal preference because I feel the code is more readable and I have never been a big fan of string concatenations. I mention this because there is a needed work around for IE 8 or old due to the lack of native support for the JSON object. For more information please see http://blogs.msdn.com/b/ie/archive/2008/09/10/native-json-in-ie8.aspx

The Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication1.Model
{
public partial class MyFormClass
{
public string Field1 { get; set; }
public string Field2 { get; set; }

}
}
The Form

In the code below you can see I have simplified the form to contain only a couple fields but this is just to condense the code posted. Also notice that that there are three JavaScript files used. jQuery, json2 to accommodate IE8 and older, and the page specific JavaScript file.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="WebApplication1.Test" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>Test</title>
<script src="Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="Scripts/json2.js" type="text/javascript"></script>
<script src="Scripts/MyFormClassJavaScript.js" type="text/javascript"></script>

</head>

<body>

<form id="form1" runat="server">
<div>

Field 1 <asp:TextBox ID="txtField1" runat="server"></asp:TextBox>
<br />
Field 2 <input type="text" id="txtField2" /> <br />
<input type="button" onclick="DoWork()" title="Go" value="Go" />
</div>

</form>

</body>

</html>
The Web Method

In the code behind I have the following web method, as you can see I have a parameter named myFormClass of the same type as the model MyFormClass. This method doesn't have any major logic, just simply takes the submitted value throws it into a list and returns the list as a JSON string.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;
using WebApplication1.Model;
using System.Web.Script.Serialization;

namespace WebApplication1
{
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

[WebMethod]
public static string GetList(MyFormClass myFormClass)
{
//Using a list to show how lists can be returned instead of single objects
List myList = new List();

//just as the submitted value to the list, obviously this is where your business logic will be submitted.
myList.Add(myFormClass);

//used JavaScriptSerializer just for down and dirty method, there are better method of doing this.
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Serialize(myList);
}
}
}
The JavaScript

As you can see the javascript is just a simple function that uses the jQuery Ajax object to post to the web method. Something that you may not recognize is the data filter that is handling the d object that .Net is adding to the JSON object that I serialized. For more information about this data filter see http://encosia.com/never-worry-about-asp-net-ajaxs-d-again/.

All I am doing with the return data object is looking through the array using the jQuery .each function and displaying in an alert window.

The key piece to notice is the JSON.Stringify function I used to create an object with the same name as the parameter of the web method, in this case myFormClass. The value of this object is another object that has two values named Field1 and Field2 which are set to the corresponding text boxes. These are name are extremely import and must match exactly, it is case sensitive, as the property in my model class.

function DoWork()
{
alert('I fired!');
$.ajax({
type: "POST",
url: "Test.aspx/GetList",
data: JSON.stringify({ myFormClass:
{
Field1: $('#txtField1').val(),
Field2: $('#txtField2').val()
}
}),
contentType: "application/json; charset=utf-8",
dataFilter: function (data) {
// This boils the response string down
// into a proper JavaScript Object().
var msg = eval('(' + data + ')');

// If the response has a ".d" top-level property,
// return what's below that instead.
if (msg.hasOwnProperty('d'))
return msg.d;
else
return msg;
},
success: function (msg) {
// This will now output the same thing
// across any current version of .NET.
$.each(msg, function (key, data) {
alert('Field1: ' + data.Field1 + ' Field2: ' + data.Field2);
});
},
error:function( jqXHR, textStatus, errorThrown ){
alert(textStatus + " : " + errorThrown);
}
});

}
Conclusion

As you can see this is a really simple example but clearly outlines a quick and easy method to utilize model binding when submitting to a web method from a traditional ASP.Net web form.


*** All Content is provided As Is ***