partialview - ASP.NET MVC-Combina el resultado de Json con ViewResult
return partialview (4)
¿Puedo devolver un resultado de Json que contenga también una vista renderizada?
Lo necesito para devolver el nuevo ID de un formulario enviado junto con su HTML y algunas otras propiedades.
También puede ser útil cuando necesito devolver dos (o más) resultados de vista de una acción dentro de un objeto Json.
¡Gracias!
En el primer caso, creo que solo puede devolver HTML, pero incrustar los datos en el formulario devuelto. Use jQuery para acceder a los datos en su devolución de llamada exitosa.
$.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();
}
});
En el segundo caso, una vista compartida que toma dos o más ViewNames y usa RenderPartial es probablemente una mejor solución que devolver HTML a través de JSON.
Multiview.aspx
...
<% foreach (string viewName in Model.Views)
{
Html.RenderPartial( viewName );
}
%>
Entonces en tu acción:
public ActionResult MyAction(...)
{
... set up model with data
model.Views = new List<string> { "View1", "View2" };
return View( "Multiview", model );
}
Esto puede ser un poco intrincado (y estoy escribiendo sobre la parte superior de mi cabeza) pero es posible que desee crear su propia subclase de ActionResult y también implementar un ResultFilter que intercepte estos tipos específicos de ActionResult y renderice las Vistas relevantes y rellene un JsonResultar y devolverlo.
Por ejemplo puedes definir:
public CompoundResult: ActionResult
{
public string ViewName { get; set; }
public JsonResult JsonResult { get; set; }
public CompoundResult(string viewName, JsonResult jsonResult)
{
ViewName = viewName;
JsonResult = jsonResult;
}
}
y luego en un ResultFilter, renderice la vista relevante y fíjela en el lugar relevante en el JsonResult y finalmente devuelva el JsonResult al cliente.
Aparte de todo esto, es posible que desee cambiar su enfoque sobre cómo hacerlo, por ejemplo. puede intentar devolver una vista completa (es decir, HTML) desde su acción, una parte de la cual es la vista que desea devolver pero que también incluye información adicional que de lo contrario habría estado en su objeto JSON. Puede sacar los componentes relevantes del HTML devuelto usando operaciones jQuery simples en el lado del cliente.
He estado pensando en este problema por un tiempo. Mi solución es similar a devolver el HTML de vista parcial como una cadena JSON, pero al contrario. Devuelve una vista parcial con JSON incrustado en ella. No me gustó este enfoque hasta que jQuery 1.4.3 fusionó su método .data () con el atributo de datos HTML 5. Esto hace que sea mucho más fácil generar JSON en una vista MVC de ASP.NET y leerlo a través de jQuery.
Vea el ejemplo ... No es perfecto, pero me gusta mucho más que crear entradas de formulario ocultas o ayudantes que representan la vista parcial antes de devolverla.
Vista parcial:
<div id="content">
<h1>Some Title</h1>
<p>Ipsum Lorem</p>
</div>
<div id="dataDiv" data-stuff=''{ "name": "Jason", "color": "Blue"}''></div>
JavaScript que lee el JSON
$(document).ready(function () {
var name = $(''#dataDiv'').data(''stuff'').name;
var color = $(''#dataDiv'').data(''stuff'').color;
alert(name + '' '' + color);
});
Esto puede parecer ir en contra del "principio de responsabilidad única" (si lo aplica a las vistas). Sin embargo, si su aplicación requiere que ambos datos se transmitan en una respuesta, entonces no veo nada de malo en ello. Y mientras su modelo esté construido correctamente, no irá en contra de ningún principio de diseño.
También puede representar un PartialViewResult a una cadena, y luego pasar esta cadena a través de JSON a su vista, representándola en su página usando jQuery.
Puede verlo en esta publicación: http://www.atlanticbt.com/blog/asp-net-mvc-using-ajax-json-and-partialviews/ .
He creado una extensión para que sea más fácil:
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();
}
}
}
En mi controlador lo llamo así:
const string msg = "Item succesfully updated!";
return new JsonResult
{
Data = new
{
success = true,
message = msg,
view = this.RenderPartialView("ProductItemForm", model)
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
Donde "este" es el controlador en el caso, "ProductItemForm" es mi vista y "modelo" es mi objeto productItem :)
Espero que esto ayude ;)