Aquí es una manera de tomar ventaja de la Content-Type
devuelto por cada resultado respectivo. Estamos utilizando esto para enviar información de error, y ya hay JS en su lugar para mostrar mensajes, por lo que obtenemos la vista parcial que queremos o control de información para informes de errores, etc.
Como referencia, una vista parcial devuelve text/html
y una respuesta JSON debería devolver application/json
.
Como de costumbre, la parte divertida está en el lado de Javascript, y el JQuery ajax()
no decepciona aquí!
En su controlador, simplemente devuelva PartialView()
o Json(model,)
según corresponda; lo estamos usando en el formato try/catch
.
public ActionResult Edit(int id) {
try {
var model = getYourModel();
return PartialView("Edit", model);
}
catch (Exception ex) {
var mi = new MessageInfo(MessageType.Error, String.Format("Edit failed: {0}", ex.Message), true);
return Json(mi, "application/json", JsonRequestBehavior.AllowGet);
}
}
En el lado JS, estamos utilizando la siguiente función. Tenga en cuenta que debe volver a establecer cualquier evento de JQuery enganchado en $(document).ready()
desde el nivel de página inicial GET, por lo que tenemos un parámetro de devolución de llamada.
function getPartialView(action, controller, model, divId, callback) {
var url = "/" + controller + "/" + action + "/";
$.ajax({
type: "GET",
url: url,
data: model,
success: function (data, textStatus, jqXHR) {
var ct = jqXHR.getResponseHeader("Content-Type");
var mx = ct.match("text\/html");
if (mx != null) {
$(divId).html(data);
if (callback) {
callback($(divId));
}
}
else {
addMessage(data.type, data.title, data.text, data.sticky);
}
},
error: function (jqXHR, textStatus, errorThrown) {
addMessage(3, "\"" + url + "\": Failed", textStatus + ": " + errorThrown, false);
}
});
}
El único poco complicado está comprobando la cabecera Content-Type
en la respuesta, y de actuar en consecuencia. Tenga en cuenta que estamos "haciendo trampa" al asumir JSON si no fuera HTML. Estamos llamando a nuestra función preexistente addMessage()
, haga lo que necesite!
Y, por último, he aquí un ejemplo de elemento de ancla con onclick
que apunta a getPartialView()
arriba.
<a href="#" onclick="getPartialView('Action', 'Controller', model, '#partialviewdivid', function(dvx) { connectJqueryEvents(dvx); })">Cancel</a>
Obras Gran ...
excepción de formulario envía a través de Ajax.BeginForm()
donde la carga útil JSON es tratada erróneamente como HTML debido a la insuficiente validación de Content-Type
. El resultado es que su div
obtiene un poco de JSON, que básicamente no se procesa como HTML. La devolución de llamada AjaxOptions.OnSuccess
se ejecuta, pero es demasiado tarde para su DOM en ese momento.
hay una solución sencilla, pero por desgracia, requiere una pequeña reparación a jquery-unobtrusive-ajax.js
porque la función asyncOnSuccess()
era miope como está escrito.
function asyncOnSuccess(element, data, contentType) {
var mode;
if (contentType.indexOf("application/x-javascript") !== -1) {
return;
}
if (contentType.indexOf("application/json") !== -1) {
return;
}
...snip...
}
En la versión OOTB, la segunda if
declaración no se encuentra; añadiendo que es la solución necesaria para evitar que golpee su carga JSON en el DOM.
Con esta corrección en su lugar, la carga JSON pasa a su AjaxOptions.OnSuccess
Javascript, y puede continuar si es necesario.
Sí Usted puede obtener tanto
Esperamos que usted sabe ya que usted está enviando JSON, que podría devolver cualquier tipo de modelo, y dejar que el Javascript a solucionar el problema; hasOwnProperty()
es muy útil allí. Así que, obviamente, puede enviar de vuelta algo de HTML de vista a través del ya mencionado RenderViewToString()
.
De hecho, eso es lo que es una respuesta ParcialView. Y aunque no lo deletree del todo, esta es la solución: haga que sus métodos AJAX devuelvan un ParialView renderizado utilizando el mismo control de usuario que utilizó para representar inicialmente esa parte de la página. Para ello, escriba return PartialView (modelo) en lugar de return Json (modelo). –
Gracias. Esa es de hecho una mejor explicación :) – Paddy
Craig, eso es lo que hago ahora. Mi problema es que quiero devolver tanto Html como Json, o dicho de otro modo: quiero que el html resultante devuelto por PartialView devuelto y luego envuelto en Json, para poder enviar otros datos también. Algo así como este tipo: http://stackoverflow.com/questions/1168791/returning-a-rentered-html-partial-in-a-json-property-in-asp-net-mvc supongo lo anterior funcionaría, pero me gustaría saber cómo otros manejan esto. – bgeek