これを行うにはさまざまな方法があると確信しています。コントローラーからビューを手動でレンダリングし、レンダリングされたビューを 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 );
匿名型を返していることに注意してください。レンダリングされたビューの文字列プロパティがある限り、任意の (シリアル化可能な) 型を返すことができます。
テスト
手動レンダリングを使用するアクションをテストするには、わずかな変更が必要です。これは、ビューが MVC パイプラインでレンダリングされるよりも少し前にレンダリングされるためです。
手動レンダリング
- アクションメソッドを入力してください
- ビューを明示的にレンダリングする <-- これにより、呼び出しアクションのテストが難しくなります
- 終了アクション メソッド
自動レンダリング
- アクションメソッドを入力してください
- ビューの結果を作成する
- 終了アクション メソッド
- ビューの結果を処理する (ビューをレンダリングする)
つまり、私たちの手動レンダリング プロセスは、テストを困難にする他のさまざまな操作 (ビルド マネージャーと対話してビューをコンパイルするなど) を開始します。
ビューの実際のコンテンツではなく、アクション メソッドをテストしたいと仮定すると、ホストされた環境でコードが実行されているかどうかを確認できます。
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
は安価です (ボンネットの下では、単純に null チェックです)。