[Json]Jquery解析Asp.net MVC的JsonResult格式数据

As I was looking around for ways to enable Ajax in the current ASP.NET MVC release I found a couple of things that I found pretty useful and thought I should share.

The J in Ajax (JQuery)

The muscle behind the actual asynchronous calls comes from JavaScript. I looked around at a bunch of existing JavaScript libraries and settled on JQuery because of the way it leverages existing CSS knowledge. The three things that the library should do easily are:

  1. Help me easily display an "updater" to let user know something is happening (i.e. loading data),
  2. Assist in making the actual Ajax call without any hassle,
  3. and, most importantly, let me get 1 and 2 working without headaches.

Here is how jQuery helps in the three cases:

  1. The "updater":
    $('#updater').show();
    $('#updater').hide();
    Notice the way jQuery uses the standard CSS id selector. Could it be any easier?
  2. jQuery has the following Ajax calls available in its library:
    object.load( )
    $.get( )
    $.post( )
    $.getJSON( )
    This takes away (hides) all of the XmlHttp object nonsense from the whole Ajax call.
  3. See 1 and 2

ASP.NET MVC

There are tons of good posts/tutorials on exactly how the ASP.NET MVC model works so I will not attempt to get into it too much here. The most important thing to know is that there are three things working together:

  1. The Controller,
  2. The Model, and
  3. The View

The controller handles all of the requests, asks the model for data, and then instructs the view to present the data (if any) returned.

Routes

One of the neat things about the MVC framework is the notion of routes. The default route setup is as follows:

   1:  routes.MapRoute(
   2:          "Default",                                              // Route name
   3:          "{controller}/{action}/{id}",                           // URL with parameters
   4:          new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
   5:  );

This simply means that, from the root of your web app, whenever a URL of the form http://root/foo/baz/bar is presented, the routing engine will call the foo controller with the baz action while supplying it with the bar id.

Some Code

Enough explanation, now to some code!

The Model

Since this is not an exercise in using the database, I created a simple Model class for students:

   1:  public class Student
   2:  {
   3:     public string FirstName { get; set; }
   4:     public string LastName { get; set; }
   5:     public int StudentId { get; set; }
   6:          
   7:     public static IQueryable<Student> GetStudentDataList()
   8:     {
   9:        return new List<Student>() 
  10:        {
  11:           new Student { FirstName = "John", LastName = "Smith", StudentId = 1},
  12:           new Student { FirstName = "Susan", LastName = "Connor", StudentId = 2},
  13:           new Student { FirstName = "Bryan", LastName = "Jones", StudentId = 3},
  14:           new Student { FirstName = "Lucy", LastName = "Vargas", StudentId = 4},
  15:           new Student { FirstName = "Robert", LastName = "Jimenez", StudentId = 5},
  16:           new Student { FirstName = "Seth", LastName = "Juarez", StudentId = 6},
  17:           new Student { FirstName = "David", LastName = "Meeks", StudentId = 7},
  18:           new Student { FirstName = "Olivia", LastName = "Rassmusen", StudentId = 8},
  19:           new Student { FirstName = "Viola", LastName = "Masterson", StudentId = 9},
  20:           new Student { FirstName = "Russel", LastName = "Jones", StudentId = 10}
  21:        }
  22:        .AsQueryable<Student>();
  23:     }
  24:  }

This simply creates a new list of Students and returns them as an IQueryable.

The Controller

Since I want to only pass JSON serialized objects over the wire when making the Ajax calls, there is a handy return type for the action in the controller called JsonResult:

   1:  public JsonResult Find(string name)
   2:  {
   3:     // To simulate "wait"
   4:     System.Threading.Thread.Sleep(1500);
   5:          
   6:     return new JsonResult
   7:     {
   8:        Data = (from student in Student.GetStudentDataList()
   9:                where student.LastName.StartsWith(name)
  10:                select student).ToArray<Student>()
  11:     };
  12:  }

This will serialize the data out in the JSON format. Now for the actual interesting part:

The View

The html for this example is VERY simple:

   1:  <div id="query">
   2:        <%= Html.TextBox("textSearch") %>&nbsp;
   3:        <a href="#" id="linkFind">Find</a>&nbsp;&nbsp;&nbsp; 
   4:        <span class="update" id="updater">
   5:              <img src="<%= AppHelper.ImageUrl("indicator.gif") %>" alt="Loading" />
   6:              &nbsp;Loading...&nbsp;&nbsp;&nbsp;
   7:        </span>
   8:  </div>
   9:   <div class="label">Students:</div> 
  10:  <div id="studentList"></div>

There is a search box, a link, and update panel, and a div (studentList) that will be populated by the Ajax call. This is where the magic of the routing engine coupled with the JQuery Ajax call comes together:

 

   1:  $(document).ready(
   2:     function()
   3:     {
   4:        // Hide update box
   5:        $('#updater').hide();
   6:                  
   7:        var retrieveData = function(path,  query,  funStart,  funEnd, funHandleData)
   8:        {
   9:           // for displaying updater
  10:           funStart();
  11:                          
  12:           // retrieve JSON result
  13:           $.getJSON(
  14:              path,
  15:              { name : query },
  16:              function(data)
  17:              {
  18:                 // handle incoming data
  19:                 funHandleData(data);
  20:                 // for hiding updater
  21:                 funEnd();
  22:              }
  23:           );
  24:        };
  25:                  
  26:        // adding handling to find link
  27:        $('#linkFind').click(
  28:           function(event)
  29:           {
  30:              event.preventDefault();
  31:              retrieveData(
  32:                 // mvc route to JSON request
  33:                 '/Student/Find/', 
  34:                 // query from textbox
  35:                 $('#textSearch')[0].value, 
  36:                 // function to show updater
  37:                 function() { $('#updater').show(); }, 
  38:                 // function to hide updater
  39:                 function() { $('#updater').hide(); },
  40:                 // retrieving the data
  41:                 function(data)
  42:                 {
  43:                    // clear students (if any)
  44:                    $('#studentList > div').remove();
  45:                    // add students
  46:                    for(s in data)
  47:                    {
  48:                       var student = data[s];
  49:                       $('#studentList').append('<div>(' +  student.StudentId ... you get the idea                 
  50:                     }
  51:                 }
  52:              );
  53:            }
  54:         );
  55:      }
  56:  );

The retrieveData function uses the JQuery $.getJSON call to retrieve the data. It takes as arguments the path to the controller (remembering routes), the argument (in this case the query) that the controller action expects, as well as a couple of functions. These functions will handle the cases where the  request is started, the request is ended, and what to do with the data that is returned. Subsequently we add the event handler to the link that initiates the find request. Notice that we are passing in '/Student/Find/' as the path since we are using the Find action on the StudentController. The argument is passed in from the search text box. This sets into motion the asynchronous request to the controller. The controller then returns a JSON serialized array of Student objects. Once the data is received, the studentList div is then cleared and repopulated.

Screenshot

The request:

request

The response:

response

Conclusion

Hopefully this has been helpful! It was fun putting everything together. Feel free to send me an email or leave a comment on this post if there are any suggestions/comments.

Code

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏