Ecco un modo per sfruttare il Content-Type
restituito da ogni rispettivo risultato. Stiamo usando questo per rispedire informazioni di errore, e c'è già js in atto per visualizzare i messaggi, in modo da ottenere sia la vista parziale che vogliamo, o informazioni di controllo per la segnalazione degli errori, ecc
Per riferimento, una vista parziale torna text/html
e una risposta JSON dovrebbe restituire application/json
.
Come al solito, la parte divertente è sul lato JavaScript, e il JQuery ajax()
non delude qui!
Nel controller, è sufficiente restituire PartialView()
o Json(model,)
come appropriato; lo stiamo utilizzando nel 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);
}
}
Sul lato JS, stiamo utilizzando la seguente funzione. Nota che devi ristabilire tutti gli eventi JQuery che hai agganciato in $(document).ready()
dal GET di livello pagina iniziale, quindi abbiamo un parametro di callback.
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);
}
});
}
L'unica parte difficile sta controllando la Content-Type
intestazione nella risposta, e comportarsi di conseguenza. Si prega di notare che stiamo "ingannando" assumendo JSON se non fosse HTML. Stiamo chiamando la nostra funzione pre-esistente addMessage()
, facciamo tutto il necessario!
Infine, ecco un esempio di elemento di ancoraggio con onclick
targeting getPartialView()
precedente.
<a href="#" onclick="getPartialView('Action', 'Controller', model, '#partialviewdivid', function(dvx) { connectJqueryEvents(dvx); })">Cancel</a>
Opere Grande ...
Fatta eccezione per la forma sostiene tramite Ajax.BeginForm()
in cui il carico utile JSON è trattato erroneamente come HTML dovuta alla convalida insufficiente di Content-Type
. Il risultato è che al tuo div
viene aggiunto un JSON, che in pratica non viene visualizzato come HTML. Il callback AjaxOptions.OnSuccess
viene eseguito, ma a questo punto è troppo tardi per il DOM!
c'è una soluzione semplice, ma purtroppo richiede un piccolo riparazione al jquery-unobtrusive-ajax.js
perché la funzione asyncOnSuccess()
era miope come scritto.
function asyncOnSuccess(element, data, contentType) {
var mode;
if (contentType.indexOf("application/x-javascript") !== -1) {
return;
}
if (contentType.indexOf("application/json") !== -1) {
return;
}
...snip...
}
Nella versione OOTB, il secondo if
affermazione manca; aggiungendo è la correzione necessaria per evitare di sbattere il payload JSON nel DOM.
Con questa correzione in posizione, il payload JSON passa nel tuo AjaxOptions.OnSuccess
Javascript e puoi procedere se necessario.
Sì è possibile ottenere entrambi
Speriamo che si conosce in quanto si sta inviando JSON, si potrebbe restituire qualsiasi tipo di modello, e lasciare che il Javascript sorta fuori; hasOwnProperty()
è utile lì. Quindi, ovviamente, è possibile inviare un po 'di vista HTML tramite il già citato RenderViewToString()
.
In effetti, questo è proprio ciò che una risposta di PartialView è. E anche se non lo scrivi abbastanza, questa è la soluzione: i tuoi metodi AJAX restituiscono un partial parziale renderizzato usando lo stesso controllo utente che hai usato per rendere inizialmente quella parte della pagina. Lo fai scrivendo return PartialView (modello) invece di restituire Json (modello). –
Grazie. Questa è davvero una spiegazione migliore :) – Paddy
Craig, questo è quello che faccio ora. Il mio problema è che voglio restituire sia Html che Json - o mettere altrimenti: voglio l'html risultante che viene restituito da PartialView restituito e quindi includerlo in Json, in modo che possa inviare anche altri dati. Un po 'come questo ragazzo: http://stackoverflow.com/questions/1168791/returning-a-rentered-html-partial-in-a-json-property-in-asp-net-mvc immagino quanto sopra funzionerebbe, ma mi piacerebbe sapere come gli altri gestiscono questo. – bgeek