A revised version can be found here
About four weeks ago I went to a small event for developers where one of the speakers (christian dalager) compared Ruby on Rails to Asp.Net Mvc. One of the things that really caught my attention in Ruby on Rails was the ability to have an Action serve content in various formats like Json, Xml or Html just by changing the file extension of the requested resource.
I thought it would be cool if you could do something similar in Asp.net MVC and found it to be quite easy, however if you want to serve your content in Xml, you need to download MvcContrib.
To do this, we need to create a new controller that we can inherit from.
The Controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
| /// <summary>
/// A base controller that will enable you to serve your data in either Json, Xml, Html
/// </summary>
public abstract class FormatController : Controller
{
/// <summary>
/// The Key to extract the format from Route Data
/// </summary>
private const string FORMAT_KEY = "Format";
/// <summary>
/// The type of files we can server the requested content in
/// </summary>
public enum FileFormat { Html, Json, Xml }
protected FormatController()
{
// Our Default format
RequestedFormat = FileFormat.Html;
}
/// <summary>
/// The format that has been requested
/// </summary>
protected FileFormat RequestedFormat { get; private set; }
/// <summary>
/// Occurs before an action is executed
/// </summary>
/// <param name="filterContext"></param>
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
var routeValues = filterContext.RouteData.Values;
if (routeValues.ContainsKey(FORMAT_KEY))
{
var requestedFormat = routeValues[FORMAT_KEY].ToString();
if (IsValidFormat(requestedFormat))
{
RequestedFormat = (FileFormat)Enum.Parse(typeof(FileFormat), requestedFormat, true);
}
}
}
/// <summary>
/// Verifies that the requested format is one that can be servered
/// </summary>
/// <param name="requestedFormat"></param>
/// <returns></returns>
private bool IsValidFormat(string requestedFormat)
{
return Enum.GetNames(typeof(FileFormat)).Any(format => format.ToLower() == requestedFormat.ToLower());
}
/// <summary>
/// Returns the content in the requested format
/// </summary>
/// <param name="viewModel">Viewmodel</param>
/// <returns>ActionResult</returns>
protected ActionResult FormatView(object viewModel)
{
switch (RequestedFormat)
{
case FileFormat.Html:
return View(viewModel);
case FileFormat.Json:
return Json(viewModel);
case FileFormat.Xml:
return new XmlResult(viewModel);
default:
throw new FormatException(string.Concat("Cannot server the content in the request format: ", RequestedFormat));
}
}
} |
Setting it up
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| public class Pizza
{
public int Number { get; set; }
public string Name { get; set; }
public string Price { get; set; }
}
public class HomeController : FormatController
{
public ActionResult Index()
{
var pizzas = new[]
{
new Pizza {Number = 1, Name = "Pizza 1", Price = "$10"},
new Pizza {Number = 2, Name = "Pizza 2", Price = "$13"},
new Pizza {Number = 3, Name = "Pizza 3", Price = "$20"}
};
return FormatView(pizzas);
}
} |
1
2
3
4
5
6
| // Add this to Global.asax
routes.MapRoute(
"Format",
"{controller}/{action}.{format}/{id}",
new {id = ""}
); |
Fire up your application and then type something like “home/index.xml” or “home/index.json” in the browser.
Finale word
Imaging that on your website you have different categories that contain products, by applying this technique you will be able to create a REST like webservice for your users in no time, everyone will be able to integrate your website into their own.
Sharing data has never been easier, this is so awesome.
I have submittet this piece of code (and some other stuff) to MvcContrib, I hope that it makes into the project.
Further reading
A revised version can be found here
Controllers and Action Methods in MVC Applications
JSON (JavaScript Object Notation)