Подтвердить что ты не робот

ASP.NET MVC - Объединить результат Json с ViewResult

Можно ли вернуть результат Json, который также содержит рендеринг?

Мне нужно, чтобы он возвращал новый идентификатор представленной формы вместе со своим HTML и некоторыми другими свойствами.

Также это может быть полезно, когда мне нужно вернуть два (или более) результата просмотра из одного действия внутри объекта Json.

Спасибо!

4b9b3361

Ответ 1

Вы также можете отобразить 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:)

Надеюсь, что это поможет;)

Ответ 2

В первом случае, я думаю, вы можете просто вернуть 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, вероятно, является лучшим решением, возвращающим HTML через JSON.

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

Ответ 3

Я некоторое время думал об этой проблеме. Мое решение аналогично возврату частичного представления HTML как строки JSON, но наоборот. Верните частичный вид с встроенным в него JSON. Мне не понравился этот подход, пока jQuery 1.4.3 не объединил свой .data() с атрибутом данных HTML 5. Это упрощает создание JSON в представлении ASP.NET MVC и считывает его через jQuery.

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

Частичный вид:

<div id="content">
  <h1>Some Title</h1>
  <p>Ipsum Lorem</p>
</div>
<div id="dataDiv" data-stuff='{ "name": "Jason", "color": "Blue"}'></div>

JavaScript, который читает JSON

$(document).ready(function () {
  var name = $('#dataDiv').data('stuff').name;
  var color = $('#dataDiv').data('stuff').color;
  alert(name + ' ' + color);
});

Возможно, это противоречит принципу "единой ответственности" (если вы применяете его к представлениям). Однако, если ваше приложение требует, чтобы в ответ были переданы обе части данных, я не вижу в этом ничего плохого. И пока ваша модель будет построена правильно, она не будет противоречить никаким принципам дизайна.

Ответ 4

Это может быть немного взломанным (и я пишу сверху), но вы можете создать свой собственный подкласс 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. Вы можете вынуть соответствующие компоненты из возвращаемого HTML, используя простые операции jQuery на стороне клиента.