2009-08-26 4 views
0

У Rails есть приятная идиома, которая позволяет вам иметь один метод действия, который возвращает правильно сформированные данные (json, xml, только данные) на основе формат, указанный клиентом (или же выводится из запроса. это выглядит примерно так ...Каков наилучший способ обработки возвращаемых нескольких форматов в ASP.NET MVC

respond_to do |format| 
    format.html #edit.html.erb 
    format.json {render :text=> <your json here>), :layout=> false} 
    format.xml ... 

end 

Что является предпочтительным способом сделать это в ASP.NET MVC? в идеале я хотел бы, чтобы каркас работать так же, как Rails (например, иметь возможность возвращать ViewData должным образом отформатированный для формата, указанного клиентом, или же выведенного из самого запроса).

Rails также позволяет создавать представления, специфичные для каждого типа, давая вам возможность по существу возвращать одни и те же данные ко всем представлениям и позволяя им корректно обрабатывать форматирование данных (так что у вас есть представление, которое строит xml, другое, которое строит json и еще другой, который строит html). Возможно ли это с помощью ASP.NET MVC? Фактически, эта модель, по-видимому, лучше всего подходит для разделения проблем imho, поскольку она позволяет контроллерам возвращать агностические данные вида, тогда как большинство подходов, которые я вижу сегодня (включая вышеприведенную строку «format.json ....: layout => false ») преобразование JSON внутри контроллера и возвращает эти данные непосредственно клиенту с запросом на этот формат.

В любом случае ... предложения, мысли, рекомендации?

Благодаря

ответ

2

В ASP.NET MVC, действия контроллера обычно возвращают объекты, которые вытекают из ActionResult, который затем вызывается средой выполнения при генерации потока ответа.

Из-из-коробки у вас есть несколько классов, которые проистекают из ActionResult - ContentResult для текстовых результатов, ViewResult контента из представления, JsonResult для сериализации иерархии объекта в JSON, RedirectResult для перенаправления, и так далее.

Как правило, вы передаете результат модели и даете ей возможность решить, как сгенерировать результат, но это не обязательно должна быть одна и та же модель - при необходимости я могу передать другой объект каждому результату.

Конкретный тип результата, возвращаемого действием не «запеченный в» для подписания данного действия - вы можете легко передать в качестве параметра формата на ваши действия, и это генерировать и возвращать различные ActionResult соответственно:

public ActionResult ListProducts(string format) 
{ 
    List<Product> products = ProductService.GetAllProducts(); 
    if (format == "JSON") 
    { 
     // eg., transform model for JSON consumption 
     List<JsonProduct> jsonProducts = ProductService.ToJSON(products); 
     return Json(jsonProducts); 
    } 
    else if (format == "XML") 
    { 
     return new XmlResult(products); 
    }

// default is to return HTML from view, which expects List<Product> for model 
    return View(products); 

}

Обратите внимание, что методы Json() и View() встроены в контроллер и удобные методы для возвращения JsonResult и ViewResult переспециализируются венно. XmlResult является примером пользовательского ActionResult, который берет объект, сериализует его в XML, а затем возвращает результат как поток XML.

Пример немного надуманный, но он показывает, что контроллер организует всю работу по выбору результата и построению/преобразованию модели, которая передается этому результату. Действия контроллера должны по-прежнему быть легкими, поэтому вы разгружаете тяжелые задачи в службы, такие как загрузка модели из бизнес-уровня или преобразование объектов в одной модели в объекты другой модели, например, для потребления JSON.

+0

Единственная проблема заключается в том, что редко бывает так просто вернуть Json (ваша модель).Как правило, я ожидаю, что люди будут использовать что-то вроде JQuery или ExtJs в клиенте, для чего Json (или xml) должен быть структурирован определенным образом. Итак ... где происходит эта реструктуризация? Если мы должны сделать это в контроллере ... где/как? Кроме того, если мы это делаем, разве это не нарушает «разделение проблем»? Если мы сделаем это в представлении ... как нам изменить структуру, чтобы разумно выбрать правильный вид на основе запрошенного формата? Спасибо. – wgpubs

+0

Согласен, большую часть времени вам понадобится отдельная модель для работы с JSON. Я не понимаю, почему разделение опасений нарушается, хотя проблема контроллера заключается в том, чтобы представить модель взгляду, которая включает в себя разработку того, что должна быть эта модель, и какой точке зрения следует дать эту модель. Это необходимо для контроллера. Это определенно было бы нарушением, если бы представление выполняло работу контроллера. Я отредактировал свой образец, чтобы указать на построение модели. – Sam

+0

Я предполагаю, что я разорван на этом, потому что да, контроллер должен нести ответственность за то, как данные упаковываются и отправляются в представление ... но означает ли это, что это должно быть ответственным за такое, если это означает возвращение данные в потенциально многих форматах на основе одной или нескольких клиентских фреймворков (например, ExtJs, JQuery, Mootools и т. д.)? Вы видите, мы не просто возвращаем кучу данных здесь ... мы возвращаем данные для JQuery или FOR ExtJs. Вот где вещь разделения становится немного более неясной, а также модульные контрольные контроллеры немного более волосатые. – wgpubs

Смежные вопросы