ASP.NET MVC - 将Json结果与ViewResult结合使用

时间:2009-07-25 10:54:49

标签: asp.net-mvc json partial-views

我可以返回包含渲染视图的Json结果吗?

我需要它来返回提交表单的新ID以及HTML和其他一些属性。

当我需要从Json对象中的一个动作返回两个(或更多)视图结果时,这也很有帮助。

谢谢!

4 个答案:

答案 0 :(得分:40)

您还可以将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对象:)

希望这会有所帮助;)

答案 1 :(得分:1)

在第一种情况下,我认为你可以只返回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();
             }
});

在第二种情况下,使用两个或多个ViewNames并使用RenderPartial的共享View可能是通过JSON返回HTML的更好解决方案。

Multiview.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 );
}

答案 2 :(得分:1)

我一直在思考这个问题。我的解决方案类似于将部分视图HTML作为JSON字符串返回,但相反。返回嵌入了JSON的局部视图。在jQuery 1.4.3将他们的.data()方法与HTML 5数据属性合并之前,我不喜欢这种方法。这使得在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);
});

这似乎违反了“单一责任原则”(如果您将其应用于观点)。但是,如果您的应用程序需要在响应中传输这两个数据,那么我认为它没有任何问题。只要您的模型构造正确,它就不会违反任何设计原则。

答案 3 :(得分:0)

这可能有点hacky(我正在编写我的头脑)但您可能想要创建自己的ActionResult子类并实现ResultFilter,它将拦截这些特定类型的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中取出相关组件。