Is there an equivalent to Ruby on Rails' respond_to format.xml, etc in ASP.Net MVC?
In Ruby on Rails you can write a simple controller action such as:
def index
@movies = Movies.find(:all)
respond_to do |format|
format.html #index.html.erb
format.xml { render :xml => @movies }
format.json { render :json => @movies }
end
end
For those unfamiliar with RoR, def index
in this case would be the equivalent of public ActionResult Index()
within an ASP.Net MVC Controller and would allow the following calls:
http://example.com/Movies/Index
returns as an html page from the view index.html.erb
(think index.aspx)
http://example.com/Movies/Index.xml
returns the same data in xml format (@movies
is the object containing the data all of the views use)
http://example.com/Movies/Index.json
returns a JSON string, useful when making javascript calls needing the same data/logic
An equivalent flow in ASP.Net MVC would (if possible) likely look something like this (if it could be less verbose, even better):
public ActionResult Index()
{
Movies movies = dataContext.GetMovies();
// any other logic goes here
switch (format)
{
case "xml":
return View("XMLVIEW");
break;
case "json":
return View("JSONVIEW");
break;
default:
开发者_Python百科 return View();
}
}
This is really handy not having to keep a bunch of different actions cluttering up your controller, is there a way to do something similar in ASP.Net MVC?
On my blog, I've detailed a method of handling this that functions in a very similar way to how it functions in Ruby on Rails. You can find the link at the bottom of the post, but here is a sample of the end result:
public ActionResult Index()
{
return RespondTo(format =>
{
format.Html = () => View();
format.Json = () => Json(new { message = "hello world" });
});
}
Here's the link to the post: http://icanhascode.com/2009/05/simple-ror-respond_to-functionality-in-aspnet-mvc/
It can handle detecting the correct type via HTTP headers as well as variables in the route.
So I've been playing with this and added the following routes to RegisterRoutes():
routes.MapRoute("FormatAction", "{controller}/{action}.{format}",
new { controller = "Home", action = "Index" });
routes.MapRoute("FormatID", "{controller}/{action}/{id}.{format}",
new { controller = "Home", action = "Index", id = "" });
Now whenever I need a Controller Action to be "format aware" I simply add a string format
argument to it (such as):
// Within Home Controller
public ActionResult MovieList(string format)
{
List<Movie> movies = CreateMovieList();
if ( format == "json" )
return Json(movies);
return View(movies);
}
Now when I call /Home/MovieList
it returns the standard html view as always and if I make a call to /Home/MovieList.json
it returns a JSON serialized string of the same data passed into the view. This will work for any view model you happen to be using, I'm using a very simple list just for the sake of tinkering.
To make things even better you can even do the following within the views:
Links to /Home/MovieList
<%= Html.ActionLink("Test", "MovieList") %>
Links to /Home/MovieList.json
<%= Html.ActionLink("JSON", "MovieList", new { format = "json" }) %>
There is no built-in support for this in ASP.NET MVC. However, there is a sample REST toolkit that you can download:
- Download for ASP.NET MVC 1.0
- For ASP.NET MVC 2 the REST toolkit source code is integrated into the MVC Futures download as part of the main source code download.
Read more about the REST toolkit on Phil's blog.
The REST toolkit has "format providers" that define result types for various requests. The guidance document is available in the download for ASP.NET MVC 1.0. Here's an excerpt from the guidance document:
This controller can now return XML or JSON as the response to an HTTP GET request. The format is determined based on content type of the request or content type(s) in the Accepts header of the request.
精彩评论