est ici un moyen de tirer profit du Content-Type
retourné par chaque résultat respectif. Nous utilisons ceci pour renvoyer des informations d'erreur, et il y a déjà JS en place pour afficher les messages, donc nous obtenons la vue partielle que nous voulons, ou contrôlons les informations pour le rapport d'erreurs etc.
Pour référence, une vue partielle retourne text/html
et une réponse JSON doit renvoyer application/json
.
Comme d'habitude, la partie amusante est du côté javascript, et le JQuery ajax()
ne déçoit pas ici!Dans votre contrôleur, renvoyez simplement PartialView()
ou Json(model,)
selon le cas; nous l'utilisons au format 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);
}
}
Du côté JS, nous utilisons la fonction suivante. Notez que vous devez rétablir tous les événements JQuery que vous avez pris en charge dans $(document).ready()
à partir du GET de niveau page initial, nous avons donc un paramètre de rappel.
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);
}
});
}
Le seul peu délicat est la vérification de l'en-tête Content-Type
dans la réponse, et de se comporter en conséquence. Notez que nous "trichons" en supposant JSON si ce n'était pas du HTML. Nous appelons notre fonction addMessage()
pré-existante, faites ce que vous avez besoin! Enfin, voici un exemple d'élément Anchor avec onclick
ciblant getPartialView()
ci-dessus.
<a href="#" onclick="getPartialView('Action', 'Controller', model, '#partialviewdivid', function(dvx) { connectJqueryEvents(dvx); })">Cancel</a>
Great Works ...
Sauf pour Transmet le formulaire via Ajax.BeginForm()
où la charge utile JSON est traitée par erreur comme HTML en raison d'une validation insuffisante des Content-Type
. Le résultat est que votre div
reçoit du JSON, ce qui n'est pas rendu au format HTML. Le rappel AjaxOptions.OnSuccess
s'exécute, mais il est trop tard pour votre DOM à ce stade!
Il existe une solution simple, mais malheureusement, il nécessite une petite réparation à jquery-unobtrusive-ajax.js
parce que la fonction asyncOnSuccess()
était à courte vue comme écrit.
function asyncOnSuccess(element, data, contentType) {
var mode;
if (contentType.indexOf("application/x-javascript") !== -1) {
return;
}
if (contentType.indexOf("application/json") !== -1) {
return;
}
...snip...
}
Dans la version OOTB, la deuxième déclaration if
manque; l'ajouter est le correctif nécessaire pour l'empêcher de claquer votre charge utile JSON dans le DOM.
Avec ce correctif en place, la charge utile JSON passe dans votre AjaxOptions.OnSuccess
Javascript, et vous pouvez procéder comme nécessaire.
Oui vous pouvez obtenir deux
Espérons que vous le savez, puisque vous envoyez JSON, vous pouvez renvoyer tout type de modèle, et de laisser le genre Javascript dehors; hasOwnProperty()
est très pratique là-bas. Donc, évidemment, vous pouvez renvoyer une vue HTML via déjà mentionné RenderViewToString()
.
En effet, c'est exactement ce qu'est une réponse PartialView. Et même si vous ne l'épelez pas tout à fait, voici la solution: vos méthodes AJAX retournent une vue partielle rendue en utilisant le même contrôle utilisateur que vous avez utilisé pour rendre cette partie de la page initialement. Pour ce faire, écrivez return PartialView (model) au lieu de return Json (model). –
Merci. C'est en effet une meilleure explication :) – Paddy
Craig, c'est ce que je fais maintenant. Mon problème est que je veux renvoyer à la fois Html et Json - ou à mettre autrement: Je veux que le code HTML résultant soit retourné à partir de PartialView et ensuite envelopper dans Json, afin que je puisse aussi envoyer d'autres données. Un peu comme ça mec: http://stackoverflow.com/questions/1168791/returning-a-rentered-html-partial-in-a-json-property-in-asp-net-mvc Je suppose Ce qui précède fonctionnerait, mais j'aimerais savoir comment les autres gèrent cela. – bgeek