Есть ли эквивалент Ruby on Rails 'response_to format.xml и т.д. В ASP.Net MVC?
В Ruby on Rails вы можете написать простое действие контроллера, например:
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
Для тех, кто не знаком с RoR, def index
в этом случае будет эквивалентом public ActionResult Index()
в ASP.Net MVC Controller и позволит следующие вызовы:
http://example.com/Movies/Index
возвращается как html-страница из представления index.html.erb
(think index.aspx)
http://example.com/Movies/Index.xml
возвращает те же данные в формате xml (@movies
- это объект, содержащий данные, используемые всеми видами просмотров)
http://example.com/Movies/Index.json
возвращает строку JSON, полезную при выполнении javascript-вызовов, требующих одинаковых данных/логических
Эквивалентный поток в ASP.Net MVC (если возможно), вероятно, будет выглядеть примерно так (если он может быть менее подробным, даже лучше):
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:
return View();
}
}
Это действительно не нужно держать кучу разных действий, загромождающих ваш контроллер, есть ли способ сделать что-то подобное в ASP.Net MVC?
Ответы
Ответ 1
Итак, я играл с этим и добавил следующие пути к 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 = "" });
Теперь, когда мне нужно, чтобы действие Controller было "format aware", я просто добавляю к нему аргумент string format
(например):
// Within Home Controller
public ActionResult MovieList(string format)
{
List<Movie> movies = CreateMovieList();
if ( format == "json" )
return Json(movies);
return View(movies);
}
Теперь, когда я вызываю /Home/MovieList
, он возвращает стандартное представление html, как всегда, и если я делаю вызов /Home/MovieList.json
, он возвращает сериализованную строку JSON тех же данных, которые передаются в представление. Это будет работать для любой модели просмотра, которую вы используете, я использую очень простой список только ради возиться.
Чтобы сделать что-то еще лучше, вы можете даже сделать следующее в представлениях:
Ссылки на /Home/MovieList
<%= Html.ActionLink("Test", "MovieList") %>
Ссылки на /Home/MovieList.json
<%= Html.ActionLink("JSON", "MovieList", new { format = "json" }) %>
Ответ 2
В моем блоге я подробно описал способ обработки этого, который работает очень похоже на то, как он работает в Ruby on Rails. Вы можете найти ссылку в нижней части сообщения, но вот пример конечного результата:
public ActionResult Index()
{
return RespondTo(format =>
{
format.Html = () => View();
format.Json = () => Json(new { message = "hello world" });
});
}
Здесь ссылка на сообщение: http://icanhascode.com/2009/05/simple-ror-respond_to-functionality-in-aspnet-mvc/
Он может обрабатывать обнаружение правильного типа через HTTP-заголовки, а также переменные в маршруте.
Ответ 3
В ASP.NET MVC нет встроенной поддержки. Однако есть образец инструментария REST, который вы можете скачать:
Подробнее о наборе инструментов REST на блог Фила.
В наборе инструментов REST есть "поставщики форматов", которые определяют типы результатов для различных запросов. Руководящий документ доступен для загрузки для ASP.NET MVC 1.0. Вот выдержка из руководства:
Этот контроллер теперь может возвращать XML или JSON в качестве ответа на запрос HTTP GET. Формат определяется на основе типа содержимого запроса или типа содержимого (ов) в заголовке Accepts запроса.