Format Filter for ASP.NET MVC -- getting a little more RESTful.

I developing http://nsfw4.me, I wanted a closer-to-automated way to add extensionbased format filtering to the different controller methods. For integration'ssake, I wanted the clients which may adopt using nsfw4.me tohave an easy way to interact and understand what the outcomes of those interactionswere.  In building this site on Microsoft's newly released MVC framework,it was easy to create a RESTful interface, but I didn't see a baked in way toformat output based on requested extension.

The approach I took was create two new route entries in Global.asax.cs:
 

1:  
2: routes.MapRoute("DefaultFormat", "{controller}/{action}.{format}", 
3:                           new { controller = "Home", action = "Index", id = "", format = "html"});    
4:  
5: routes.MapRoute("DefaultFormat","{controller}/{action}/{id}.{format}",
6:                            new { controller = "Home", action = "Index",id = "", format = "html"});
7:  
8:  

Now, I would be able to pick up an extension on the requested path and act accordingly. For example, if someone visits a details link for a given object, and theywant .xml, then I can give them a serialized version of that data to suit theirneeds.  If someone visits with the default .html (or nothing at all) we cangive a standard html rendering.  

Enter the FormatFilterAttribute class.  This class hangs on a Controller methodand works its magic in the OnActionExecuted method.  It is in this method thatwe make the determination on how to handle the request.  

Note: Thisfilter requires James Newton-King'sJSON Library.

1:        public override void OnActionExecuted(ActionExecutedContext filterContext)
2:         {
3:             if (filterContext.RouteData.Values.ContainsKey("format"))
4:             {
5:                 var fmt = GetFormat(filterContext);
6:                 var obj = GetResultObject(filterContext);
7:                 switch (fmt)
8:                 {
9:                     case "xml":
10:                         if (null != obj)
11:                         {
12:                             XmlSerializer xs = new XmlSerializer(obj.GetType());
13:                             using (MemoryStream Ms = new MemoryStream())
14:                             {
15:                                 xs.Serialize(Ms, obj);
16:                                 var ret = System.Text.Encoding.UTF8.GetString(Ms.ToArray());
17:                                 filterContext.Result =new PlainTextActionResult(ret);
18:                             }
19:                         }
20:                         break;
21:                     case "json":
22:                         if (null != obj)
23:                         {
24:                             filterContext.Result =new PlainTextActionResult(
25:                                 JsonConvert.SerializeObject(obj, Formatting.Indented));
26:                         }
27:                         break;
28:                     case "html":
29:                         //DO NOTHING
30:                         break;
31:                     default:
32:                         throw new ArgumentException("Invalid format supplied");
33:                         break;
34:                 }
35:             }
36:             base.OnActionExecuted(filterContext);
37:         }
38:  

What's happening Here?

As the MVC framework processes the request to this method, we will intercept afterthe user code has run.  At this time we determine whether there was requestfor something other than a standard render and act accordingly.  If a ViewDataKeyhas been set for the attribute, we look for this object in the ViewData collection,if no key is specified, we try getting the data from the Model property of the currentViewData.  This data is then serialized back to the requesting client.  Currently,2 formats are supported: xml and json.

Try it here:

HTML: http://nsfw4.me/links/details/yahoo
JSON:  http://nsfw4.me/links/details/yahoo.json
XML:  http://nsfw4.me/links/details/yahoo.xml

It also works with creating data.   If you post the proper values (LinkId,LinkUrl) to http://nsfw4.me/links/create.xml, you will receive the result, goodor bad in xml format.  The same also applies for .json requests.

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Blog Migration - Success!

For the subscribers, I apologize if you have a slew of new and re-used posts in your reader.  I have been in the process of migrating from Community Server to SubText and then to BlogEngine.NET.  It seems as though BlogEngine.NET has a more active community than SubText which is run by the very busy Phil Haack of Microsoft fame.  I am happy to report that the migration is, for now, complete.

I decided to write a migration tool that would move the data over - I did so using the BlogML, MetaWeblog & Blogger apis, C#, WPF, and the Cook Computing XmlRpc library.  There are tools (one even comes with BlogEngine.NET) but they don't move over the linked images and since some of the posts that survived my last migration have pictures, I didn't want to move them manually... 

There was some effort involved and the code needs refactoring but all in all the utility works well.  Once I have the time to clean it up and if anyone is interested, I will post the utility and code here.

Currently rated 4.3 by 3 people

  • Currently 4.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

LINQ - Design Guidelines

Earlier, my business partner forwarded me a link to a great article by Mircea Trofin that covers, with examples, some great design guidelines for using LINQ and developing/extending with new types, libraries and the like.

The article is a great read for those of you who like an architectural view.

Check it out:

Click Here

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET Blogging Engine

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

ASP.NET 2.0 Menu Control - Safari Fix

Note: This advice is provided without warranty, guarantee and manatee.

 Getting the ASP.NET 2.0 Menu control to work with Safari (on OS X) proved itself to be a a bear -- not so much because of the solution, but because everyone blames MS for not fixing it instead of coming up with a solution.  After some tinkering with it, I found a directive I hadn't seen before:

Page.ClientTarget

As it turns out, you can simply set Page.ClientTarget = "uplevel" and the control renders perfectly in Safari.  Of course, we should ensure that we're on Safari which can be done with a simple check in Request.ServerVariables["http_user_agent"].

 All in all, it looks like this: (without the spacing of course :))

protected void Page_PreInit(object sender, EventArgs e)
{

if (Request.ServerVariables["http_user_agent"].ToLower().Contains("safari"))
{


Page.ClientTarget =

"uplevel";


}

}

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

SQL Object Generator

Updated 4/23/2007 

Here are the latest DAL Entity Generator templates for C#.

C# Entities Template
C# Entity Collections Template

These are for use with Webglimmer's SQL Object Generator.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: