Bulletproof Ajax with ASP.NET MVC

Posted by andy gaskell on Aug 2nd, 2008

After reading the excellent Bulletproof Ajax by Jeremy Keith, I thought porting the Bulletproof Books sample application to ASP.NET MVC would be a great first attempt at building an ASP.NET MVC application. One of the main points of Bulletproof Ajax is that Ajax should be used to enhance usability and not to make Ajax a requirement to access your content. My version of the Bulletproof Books Shop also makes Javascript and XMLHttpRequest support optional.

Keeping the site accessible to most web browsers took some extra work and consideration when building the Controllers. I decided that any HomeController actions would render html for the entire page.

   13         public ActionResult Index()

   14         {

   15             ViewData.Model = Product.Products;

   16             return View(“Index”);

   17         }

   18 

   19         public ActionResult AddProductToCart(string productID, int quantity)

   20         {

   21             CartController cartController = new CartController();

   22             cartController.AddProduct(productID, quantity);

   23             return Index();

   24         }

   25 

   26         public ActionResult RateProduct(string productID, string rating)

   27         {

   28             RatingController ratingController = new RatingController();

   29             ratingController.RateProduct(productID, rating);

   30             return Index();

   31         }

Controllers that refresh partial chunks of html will know how to respond to actions (add product to cart, rate a product) and render views mapped to MVC user controls. The client will make http requests to different urls based on javascript support in the browser. For example to add a product to a cart with javascript enabled, the javascript will make a post to /Cart.mvc/AddProduct and the server will response with a chunk of html. To add a product with javascript disabled the client will post to /Home.mvc/AddProductToCart and the server will respond with an entire page. The HomeController ends up forwarding the call to the appropriate controller so we’re able to avoid duplicating logic.

   28         public ActionResult DisplayCart()

   29         {

   30             Cart cart = GetCart();

   31             return View(“Cart”, cart);

   32         }

   33 

   34         public ActionResult AddProduct(string productID, int quantity)

   35         {

   36             Cart cart = GetCart();

   37             Product product = Product.Products.Find(s => s.ID == productID);

   38             cart.AddProduct(product, quantity);

   39             SetCart(cart);

   40             return View(“Cart”, cart);

   41         }

One thing I’m not sure about is state management in ASP.NET MVC, so I’m currently storing the cart and ratings in session.

   22         private Rating GetRatings()

   23         {

   24             Rating rating = System.Web.HttpContext.Current.Session["Rating"] as Rating;

   25             if (rating == null)

   26             {

   27                 rating = new Rating();

   28             }

   29             return rating;

   30         }

   31 

   32         private void SetRating(Rating rating)

   33         {

   34             System.Web.HttpContext.Current.Session["Rating"] = rating;

   35         }

You can download the source here.

Using the digg API in an ASP.NET Page

Posted by andy gaskell on Apr 20th, 2007

Digg released their API yesterday - I haven’t really done much with RESTful web services because in the .net world, most of the time SOAP/WSDL is used. I thought a very basic RESTful web service project would be useful for other .net developers.

This example gets a list of all topics that digg offers. The code is pretty simple:

// Create the web request, change the appkey to for your applications
HttpWebRequest request = WebRequest.Create("http://services.digg.com/topics?appkey=http%3A%2F%2Fgaskell.org") as HttpWebRequest;

// won't get a response from digg if UserAgent is not set
request.UserAgent = ".net"; 

// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
     // Get the response stream
     StreamReader reader = new StreamReader(response.GetResponseStream());

     DataSet ds = new DataSet();
     ds.ReadXml(reader);

     this.topicsGridView.DataSource = ds.Tables[1];
     this.topicsGridView.DataBind();
}    

Download the project or check out the live demo

Digg style custom paging for GridViews in ASP.NET

Posted by andy gaskell on Apr 12th, 2007

I’ve been on a bit of a digg kick lately and I like how they handle paging so I decided to create a GridView control that uses custom paging similar to digg’s. The algorithm is based on this post. As far as html output goes, this should be fairly close to the actual output on digg and I’m using digg’s stylesheet in the demo.

About the algorithm (from Stranger Studios):

  1. The pagination object has a “previous” and “next” button which takes the user to the next page. The previous button is disabled on the first page. Similarly, the next button is disabled on the last page.
  2. The pagination object will always display links to the first two pages and the last two pages of the set.
  3. The pagination object will always display links to the first x (adjacents in the code) pages before and after the current page.
  4. The pagination object will only show at most 5+2x links (first two + prior x + current page + next x + last two). All links not shown will be replaced by …

A little preview:
digg style paging preview

You can download the project here. I didn’t spend a ton of time testing this code, please leave any bug reports in the comments - Thanks!

Update: Changed the code a bit - paging is now handled via query string instead of posting back. Not a huge deal but the code is easier to read.

Next »