レンダリングされたビューも含む Json 結果を返すことはできますか?
送信されたフォームの新しい ID とその HTML およびその他のプロパティを返すために必要です。
また、Json オブジェクト内の 1 つのアクションから 2 つ (またはそれ以上) のビュー結果を返す必要がある場合にも役立ちます。
ありがとう!
レンダリングされたビューも含む Json 結果を返すことはできますか?
送信されたフォームの新しい ID とその HTML およびその他のプロパティを返すために必要です。
また、Json オブジェクト内の 1 つのアクションから 2 つ (またはそれ以上) のビュー結果を返す必要がある場合にも役立ちます。
ありがとう!
また、PartialViewResultを文字列にレンダリングしてから、この文字列をJSON経由でビューに渡し、jQueryを使用してページにレンダリングすることもできます。
この投稿でそれを見ることができます:http ://www.atlanticbt.com/blog/asp-net-mvc-using-ajax-json-and-partialviews/ 。
簡単にするために拡張機能を作成しました。
public static class MvcHelpers
{
public static string RenderPartialView(this Controller controller, string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = controller.ControllerContext.RouteData.GetRequiredString("action");
controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
ViewEngineResult 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);
return sw.GetStringBuilder().ToString();
}
}
}
私のコントローラーでは、次のように呼んでいます。
const string msg = "Item succesfully updated!";
return new JsonResult
{
Data = new
{
success = true,
message = msg,
view = this.RenderPartialView("ProductItemForm", model)
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
この場合、「this」はコントローラーであり、「ProductItemForm」は私のビューであり、「model」は私のproductItemオブジェクトです:)
お役に立てれば ;)
私はしばらくの間、この問題について考えてきました。私の解決策は、部分ビューの HTML を JSON 文字列として返すのと似ていますが、逆です。JSON が埋め込まれた部分ビューを返します。jQuery 1.4.3 で .data() メソッドが HTML 5 の data 属性とマージされるまで、私はこのアプローチを好まなかった。これにより、ASP.NET MVC ビュー内で JSON を生成し、jQuery 経由で読み取ることがはるかに簡単になります。
例を参照してください... 完璧ではありませんが、非表示のフォーム入力や、返す前に部分ビューをレンダリングするヘルパーを作成するよりもはるかに優れています。
部分図:
<div id="content">
<h1>Some Title</h1>
<p>Ipsum Lorem</p>
</div>
<div id="dataDiv" data-stuff='{ "name": "Jason", "color": "Blue"}'></div>
JSON を読み取る JavaScript
$(document).ready(function () {
var name = $('#dataDiv').data('stuff').name;
var color = $('#dataDiv').data('stuff').color;
alert(name + ' ' + color);
});
これは、「単一責任の原則」に反するように見える場合があります (ビューに適用する場合)。ただし、アプリケーションが応答で両方のデータを送信する必要がある場合は、問題はないと思います。モデルが適切に構築されている限り、設計原則に反することはありません。
最初のケースでは、HTML を返すだけでよいと思いますが、返されたフォームにデータを埋め込みます。jQuery を使用して、成功のコールバックでデータにアクセスします。
$.ajax({
url: '<%= Url.Action( "MyAction" )',
dataType: 'html',
data: $('form').serialize(),
success: function(data) {
$('form').html(data);
var id = $('form').find('input#formId[type=hidden]').val();
}
});
2 番目のケースでは、2 つ以上の ViewName を受け取り、RenderPartial を使用する共有ビューは、JSON を介して HTML を返すよりもおそらく優れたソリューションです。
マルチビュー.aspx
...
<% foreach (string viewName in Model.Views)
{
Html.RenderPartial( viewName );
}
%>
次に、あなたの行動で:
public ActionResult MyAction(...)
{
... set up model with data
model.Views = new List<string> { "View1", "View2" };
return View( "Multiview", model );
}
これは少しハッキーかもしれませんが(そして私は頭のてっぺんを書いています)、ActionResultの独自のサブクラスを作成し、これらの特定のタイプのActionResultをインターセプトして、関連するビューをレンダリングし、 JsonResultとそれを返します。
たとえば、次のように定義できます。
public CompoundResult: ActionResult
{
public string ViewName { get; set; }
public JsonResult JsonResult { get; set; }
public CompoundResult(string viewName, JsonResult jsonResult)
{
ViewName = viewName;
JsonResult = jsonResult;
}
}
次に、ResultFilterで、関連するビューをレンダリングし、それをJsonResultの関連する場所にマージして、最後にJsonResultをクライアントに返します。
これらすべてとは別に、これを行う方法のアプローチを変更したい場合があります。アクションから完全なビュー(つまりHTML)を返してみてください。その一部は返したいビューですが、JSONオブジェクトに含まれていたはずの追加情報も含まれています。クライアント側で簡単なjQuery操作を使用して、返されたHTMLから関連するコンポーネントを取り出すことができます。