Comment transmettre des informations d'erreur personnalisées d'une méthode ASP.NET MVC3 JsonResult
à la fonction error
(ou success
ou complete
, si nécessaire) de jQuery.ajax()
? Idéalement, j'aimerais pouvoir:
Voici une version de base de mon code:
public JsonResult DoStuff(string argString)
{
string errorInfo = "";
try
{
DoOtherStuff(argString);
}
catch(Exception e)
{
errorInfo = "Failed to call DoOtherStuff()";
//Edit HTTP Response here to include 'errorInfo' ?
throw e;
}
return Json(true);
}
$.ajax({
type: "POST",
url: "../MyController/DoStuff",
data: {argString: "arg string"},
dataType: "json",
traditional: true,
success: function(data, statusCode, xhr){
if (data === true)
//Success handling
else
//Error handling here? But error still needs to be thrown on server...
},
error: function(xhr, errorType, exception) {
//Here 'exception' is 'Internal Server Error'
//Haven't had luck editing the Response on the server to pass something here
}
});
Choses que j'ai essayées (ça n'a pas marché):
catch
catch
xhr
dans le gestionnaire d'erreurs jQueryxhr.getResponseHeader()
, etc. contenait la page d'erreur ASP.NET par défaut, mais aucune de mes informationsVous pouvez écrire un filtre d'erreur personnalisé:
public class JsonExceptionFilterAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.ExceptionHandled = true;
filterContext.Result = new JsonResult
{
Data = new
{
// obviously here you could include whatever information you want about the exception
// for example if you have some custom exceptions you could test
// the type of the actual exception and extract additional data
// For the sake of simplicity let's suppose that we want to
// send only the exception message to the client
errorMessage = filterContext.Exception.Message
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
}
et enregistrez-le ensuite en tant que filtre global ou ne s'applique qu'à des contrôleurs/actions particuliers que vous souhaitez invoquer avec AJAX.
Et sur le client:
$.ajax({
type: "POST",
url: "@Url.Action("DoStuff", "My")",
data: { argString: "arg string" },
dataType: "json",
traditional: true,
success: function(data) {
//Success handling
},
error: function(xhr) {
try {
// a try/catch is recommended as the error handler
// could occur in many events and there might not be
// a JSON response from the server
var json = $.parseJSON(xhr.responseText);
alert(json.errorMessage);
} catch(e) {
alert('something bad happened');
}
}
});
Évidemment, vous pourriez vous ennuyer rapidement pour écrire du code de traitement d'erreur répétitif pour chaque demande AJAX. Il serait donc préférable de l'écrire une fois pour toutes les demandes AJAX sur votre page:
$(document).ajaxError(function (evt, xhr) {
try {
var json = $.parseJSON(xhr.responseText);
alert(json.errorMessage);
} catch (e) {
alert('something bad happened');
}
});
et alors:
$.ajax({
type: "POST",
url: "@Url.Action("DoStuff", "My")",
data: { argString: "arg string" },
dataType: "json",
traditional: true,
success: function(data) {
//Success handling
}
});
Une autre possibilité consiste à adapter un gestionnaire d'exception global que j'ai présenté afin que, dans ErrorController, vous vérifiiez s'il s'agissait d'une demande AJAX et renvoyiez simplement les détails de l'exception au format JSON.
Les conseils ci-dessus ne fonctionneraient pas sur IIS pour les clients distants. Ils recevront une page d'erreur standard telle que 500.htm au lieu d'une réponse avec un message . Vous devez utiliser le mode customError dans web.config, ou ajouter
<system.webServer>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
ou
"Vous pouvez également aller dans IIS manager -> Pages d'erreur, puis cliquez sur le bouton , Puis sur" Modifier les paramètres de fonction ... "et définissez l'option sur" Détails. errors "alors ce sera votre application qui traitera l'erreur et pas IIS."
vous pouvez renvoyer JsonResult avec une erreur et suivre le statut côté javascript pour afficher le message d'erreur:
JsonResult jsonOutput = null;
try
{
// do Stuff
}
catch
{
jsonOutput = Json(
new
{
reply = new
{
status = "Failed",
message = "Custom message "
}
});
}
return jsonOutput ;
Mon projet MVC ne renvoyait aucun message d'erreur (personnalisé ou autre) ... J'ai constaté que cela fonctionnait bien pour moi:
$.ajax({
url: '/SomePath/Create',
data: JSON.stringify(salesmain),
type: 'POST',
contentType: 'application/json;',
dataType: 'json',
success: function (result) {
alert("start JSON");
if (result.Success == "1") {
window.location.href = "/SomePath/index";
}
else {
alert(result.ex);
}
alert("end JSON");
},
error: function (xhr) {
alert(xhr.responseText);
}
//error: AjaxFailed
});
La présentation de xhr.responseText a abouti à un message d’alerte très détaillé au format HTML.