Ответ 1
Я уверен, что существует множество способов сделать это. Я вручную визуализую представление с контроллера, а затем передаю визуализированный вид назад как часть моего ответа JSON.
Это сохраняет обязанности каждого объекта. Представления все еще расположены с использованием механизма просмотра, и их можно использовать повторно. Контроллер мало знает о представлении помимо имени и типа модели.
Ручное рендеринг
public static class RenderHelper
{
public static string PartialView( Controller controller, string viewName, object model )
{
controller.ViewData.Model = model;
using( var sw = new StringWriter() )
{
var viewResult = ViewEngines.Engines.FindPartialView( controller.ControllerContext, viewName );
var viewContext = new ViewContext( controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw );
viewResult.View.Render( viewContext, sw );
viewResult.ViewEngine.ReleaseView( controller.ControllerContext, viewResult.View );
return sw.ToString();
}
}
}
В вашем методе действий:
object model = null; // whatever you want
var obj = new {
someOtherProperty = "hello",
view = RenderHelper.PartialView( this, "_PartialName", model )
};
return Json( obj );
Обратите внимание, что я возвращаю анонимный тип. Вы можете вернуть любой (сериализуемый) тип, который вы хотите, до тех пор, пока он имеет свойство string для визуализированного представления.
Тестирование
Тестирование действия, использующего ручной рендеринг, требует небольшой модификации. Это связано с тем, что представление было немного раньше, чем это было бы показано в конвейере MVC.
Ручное рендеринг
- Введите метод действий
- Render view явно < - это затруднит проверку вызывающего действия
- Метод действия выхода
Автоматическое рендеринг
- Введите метод действий
- Создать результат просмотра
- Метод действия выхода
- Результат просмотра процесса (таким образом, отображение представления)
Другими словами, процесс ручного рендеринга запускает множество других операций, которые затрудняют тестирование (например, взаимодействие с менеджером сборки для компиляции представления).
Предполагая, что вы хотите протестировать метод действия, а не фактическое содержимое представления, вы можете проверить, выполняется ли код в размещенной среде.
public static string PartialView( Controller controller, string viewName, object model )
{
// returns false from a VS 2013 unit test, true from IIS
if( !HostingEnvironment.IsHosted )
{
// return whatever you want here
return string.Empty;
}
// continue as usual
}
Проверка HostingEnvironment.IsHosted
является недорогой (под капотом это просто нулевая проверка).