Archive

Posts Tagged ‘Ajax’

ASP.NET MVC and Unobtrusive Ajax with jQuery Part II

September 18th, 2008

In my last post, I introduced this series in which I add Ajax to an ASP.NET MVC application as a progressive enhancement, allowing the site to function without requiring JavaScript, but creating a better user experience for users with JavaScript enabled. In this post, I will discuss the feature I am working on and introduce the base controller and view code as well as introduce a minor change to the initial controller code to add support for Ajax calls/return data without breaking the standard post-based behavior.

The Target Functionality

The functionality that we will be looking at for the purpose of these posts will be a simple content page that allows comments. The comment form will exist on the content page and will call a controller that will then insert a record in the database. Since the comments live on the page with the associated content, the controller will redirect to the view that the form was submitted from (showing the content again, along with the comments). The page will be reloaded, just as you would expect from a typical form submission that redirects following the submission. Once that works, we can update the code to make the form submit via Ajax, at which point we will need to update the page through client script.

The Initial Code

The initial code is a simple controller action which makes a call to a business object that will handle inserting the comment into the database. I will be displaying a code comment as a placeholder for that code since it has very little relevance to the topic at hand.

[AcceptVerbs("POST")]
public ActionResult AddComment(string commentBody, int articleID)
{
//Logic and Database insert code...

//redirect to re-load the page
return RedirectToRoute("Default",
new { controller = "Article",
action = "Show",
id = articleID });
}

At this point, since the View for our content will re-query and display all of the associated comments all that this code needs to do is redirect the user back to the content page and the new comment will be loaded along with the rest of the comments. The above code accomplishes this redirect in a single line of code.

Updating The Controller Action

Now that we have the form in the view successfully submitting its content to the controller action through a post, we need to update the action code to distinguish between a standard post and an ajax-based post in order to return JSON when needed. One of the goals was to make any controller changes minimal. We also want to make sure that none of the business logic changes due to the addition of Ajax. So let’s take a look at the code for the first step:

[AcceptVerbs("POST")]
public ActionResult AddComment(string commentBody, int articleID, string mode)
{
   //Logic and Database insert code...

   //redirect to re-load the page
   return RedirectToRoute("Default",
      new { controller = "Article",
            action = "Show",
            id = articleID });
}

The only change we have made at this point is to add an additional string argument to the method’s signature. This “mode” argument isn’t part of the original form post, and that’s ok. Our form doesn’t need to change. The only time (at this point) the mode value will be passed is when we are making the call from JavaScript. Now we will add a simple check to see if that string has been passed. If it hasn’t been passed, then we know it was a standard post and we will perform the redirect, just like we have been doing:

[AcceptVerbs("POST")]
public ActionResult AddComment(string commentBody, int articleID, string mode)
{
   //Logic and Database insert code...

   if (!string.IsNullOrEmpty(mode) && mode == "ajax")
   {
      //handle json result for ajax call
   }
   else
   {
      //redirect to re-load the page
      return RedirectToRoute("Default",
         new { controller = "Article",
               action = "Show",
               id = articleID });
   }
}

Now all that’s left to do is return JSON formatted data if the mode has been passed. The final version of the controller action is listed below.

[AcceptVerbs("POST")]
public ActionResult AddComment(string commentBody, int articleID, string mode)
{
   //Logic and Database insert code...

   if (!string.IsNullOrEmpty(mode) && mode == "ajax")
   {
      //The comment object is returned after the data insert above
      return this.Json(comment);
   }
   else
   {
      //redirect to re-load the page
      return RedirectToRoute("Default",
         new { controller = "Article",
               action = "Show",
               id = articleID });
   }
}

This code includes a call to the Controller’s Json method (referenced as this.Json) which accepts your data object (in our case, a comment object that was returned from the omitted data insert code) and returns a JsonResult object that can be returned from the controller. The passed object is then made available to your JavaScript when it receives the Ajax result. We will take a closer look at the comment object in the next post, when we add the JavaScript that will trigger the JsonResult object being returned.

This controller action meets our goals of using the same logic regardless of the method that was used to post the form and I think the changes are fairly minimal (again, this is pretty subjective).

Coming Up

We still need to add the jQuery code required to make an Ajax call to the controller and ensure that there is a return value. After we have the code in place to make the call and run the controller code, there will be a couple more posts to explain how to handle the return data and add some other nice UX features for those with JavaScript enabled.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

.NET, ASP.NET, Ajax, JavaScript, MVC, jQuery , , , , ,

ASP.NET MVC and Unobtrusive Ajax with jQuery Part I

September 15th, 2008

I have recently started developing a website using ASP.NET MVC (preview 5). One of the things I love about the MVC framework is the total control I have over my markup. I can keep the HTML clean, use ID values that make sense and won’t change each time the page is rendered and I can add all of my own client-side interactivity using jQuery (without the id mess that web controls create).

One of my goals with this new site is to create a functional site that works and renders in a usable manner even with CSS and JavaScript disabled. In order to do this, I have been creating all of the required interactions using standard get and post operations. The next logical step is to add Ajax functionality as a progressive enhancement using jQuery. Since ASP.NET MVC is still pre-beta, there isn’t a lot of documentation or published best practices with specifics about how to best handle this through the framework. I have read several posts from others with different solutions, they range anywhere from routing hacks (including ajax or html in the url) to seperate views (one standard view and an ajax enabled view). None of the solutions I have found have been what I wanted to do, so I set some goals for how I wanted it to work and through a process of trial and error, I have a solution. Through the next couple of posts, I will outline how I am handling this. I look forward to any feedback (good or bad) and if somebody has a better solution, please let me know.

The Goals

  1. Site should work in an acceptable manner without JavaScript enabled
  2. The same view should handle both Ajax enabled and standard post/get operations
  3. All controller code should be run in either scenario except for returning the ActionResult
  4. Changes to the controller action signature should be minimal and the same approach should work for any controller action (with minimal change)

Some of these goals are no-brainers, it helped to have all of the goals in place to keep myself from creating a massive amount of “Franken-code” in order to get the site working. I also realize that using the word “minimal” when talking about code changes is subjective, so if you don’t think what I have done is minimal, feel free to comment on the posts that contain the code and we can discuss it, please just share something more than “your solution sucks…” that won’t help anybody. And, if you have any other goals that you think I shoudl keep in mind, please let me know. I can’t promise that I’ll be able to attain more than I have already planned for in this series, but if something that I haven’t thought of seems important enough, I will do my best to try to meet the new criteria.

Upcoming Posts

Stay tuned. I have the code worked out for the most part, but it hasn’t been fully implemented, so I will be posting as I make more progress and I have tested enough to feel confident that I will have working code. I’m hoping to get the first post that has any real substance out before the end of the week.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

.NET, ASP.NET, Ajax, JavaScript, MVC, jQuery , , , , ,

jQuery Rocks!

July 15th, 2008

I’ve worked with quite a few JavaScript libraries over the last couple of years. All of these libraries save a great deal of work and allow you to do pretty amazing stuff, but after a few days of learning and using jQuery… I have to say that it is the most impressive one that I’ve worked with.

jQuery has a code-to-impact ratio similar to regular expressions… lots of power packed into very little code. The big difference (other than purpose) is that unlike regular expressions, jQuery is pretty easy to read and write. The selector syntax makes writing unobtrusive JavaScript a simple task and the number of plug-ins that are available means that most common (and some not-so-common) problems have probably been solved already. All you need to do is download the plug-in and use it on your page. jQuery offers a fluent interface which allows several functions to be run in succession by chaining methods. Condensing 5 function calls into a single line of code not only works, but it is also readable.

As an ASP.NET developer, conflicts with ASP.NET Ajax are a concern, but with jQuery even if there were conflicts (there aren’t any that I’ve encountered yet) with another library, you can call a single method ($.noConflict()) and you have nothing to worry about… they seem to have thought of everything.

It rocks. You should try it. I will write more informative (and more organized) posts on jQuery in the near future… stay tuned.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Ajax, JavaScript, jQuery , ,