jquery ajaxがアクションを呼び出すときにコントローラーでスローされた例外をどのように処理しますか?
たとえば、デバッグモードまたは通常のエラーメッセージの場合に例外メッセージを表示するajax呼び出し中に、あらゆる種類のサーバー例外で実行されるグローバルJavaScriptコードが必要です。
クライアント側では、ajaxエラー時に関数を呼び出します。
サーバー側では、カスタムアクションフィルターを作成する必要がありますか?
jquery ajaxがアクションを呼び出すときにコントローラーでスローされた例外をどのように処理しますか?
たとえば、デバッグモードまたは通常のエラーメッセージの場合に例外メッセージを表示するajax呼び出し中に、あらゆる種類のサーバー例外で実行されるグローバルJavaScriptコードが必要です。
クライアント側では、ajaxエラー時に関数を呼び出します。
サーバー側では、カスタムアクションフィルターを作成する必要がありますか?
回答:
サーバーが200以外のステータスコードを送信すると、エラーコールバックが実行されます。
$.ajax({
url: '/foo',
success: function(result) {
alert('yeap');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
グローバルエラーハンドラーを登録するには、次の$.ajaxSetup()
メソッドを使用できます。
$.ajaxSetup({
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
別の方法は、JSONを使用することです。そのため、例外をキャッチしてJSON応答に変換するカスタムアクションフィルターをサーバーに作成できます。
public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
filterContext.Result = new JsonResult
{
Data = new { success = false, error = filterContext.Exception.ToString() },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
次に、この属性でコントローラーアクションを装飾します。
[MyErrorHandler]
public ActionResult Foo(string id)
{
if (string.IsNullOrEmpty(id))
{
throw new Exception("oh no");
}
return Json(new { success = true });
}
そして最後にそれを呼び出します:
$.getJSON('/home/foo', { id: null }, function (result) {
if (!result.success) {
alert(result.error);
} else {
// handle the success
}
});
error
コールバックが実行されます。
グーグルした後、MVCアクションフィルターに基づく簡単な例外処理を記述します。
public class HandleExceptionAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
filterContext.Exception.Message,
filterContext.Exception.StackTrace
}
};
filterContext.ExceptionHandled = true;
}
else
{
base.OnException(filterContext);
}
}
}
そしてglobal.ascxに書きます:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleExceptionAttribute());
}
次に、このスクリプトをレイアウトまたはマスターページに記述します。
<script type="text/javascript">
$(document).ajaxError(function (e, jqxhr, settings, exception) {
e.stopPropagation();
if (jqxhr != null)
alert(jqxhr.responseText);
});
</script>
最後に、カスタムエラーをオンにする必要があります。そしてそれを楽しんでください:)
残念ながら、どちらの答えも私には良くありません。驚くべきことに、解決策ははるかに簡単です。コントローラから戻る:
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);
そして、それを好きなようにクライアントの標準HTTPエラーとして処理します。
int
ます。また、これを行うと、結果はajax
success
ハンドラーではなくハンドラーに渡されerror
ます。これは予想される動作ですか?
時間がないので問題なく動いたので、すぐに解決しました。私はより良いオプションは例外フィルターを使用することだと思いますが、おそらく私の解決策は単純な解決策が必要な場合に役立つでしょう。
私は次のことをしました。コントローラーメソッドで、Data内に "Success"プロパティを持つJsonResultを返しました。
[HttpPut]
public JsonResult UpdateEmployeeConfig(EmployeConfig employeToSave)
{
if (!ModelState.IsValid)
{
return new JsonResult
{
Data = new { ErrorMessage = "Model is not valid", Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
try
{
MyDbContext db = new MyDbContext();
db.Entry(employeToSave).State = EntityState.Modified;
db.SaveChanges();
DTO.EmployeConfig user = (DTO.EmployeConfig)Session["EmployeLoggin"];
if (employeToSave.Id == user.Id)
{
user.Company = employeToSave.Company;
user.Language = employeToSave.Language;
user.Money = employeToSave.Money;
user.CostCenter = employeToSave.CostCenter;
Session["EmployeLoggin"] = user;
}
}
catch (Exception ex)
{
return new JsonResult
{
Data = new { ErrorMessage = ex.Message, Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
return new JsonResult() { Data = new { Success = true }, };
}
後のajax呼び出しで、このプロパティに例外があるかどうかを確認するように要求しました。
$.ajax({
url: 'UpdateEmployeeConfig',
type: 'PUT',
data: JSON.stringify(EmployeConfig),
contentType: "application/json;charset=utf-8",
success: function (data) {
if (data.Success) {
//This is for the example. Please do something prettier for the user, :)
alert('All was really ok');
}
else {
alert('Oups.. we had errors: ' + data.ErrorMessage);
}
},
error: function (request, status, error) {
alert('oh, errors here. The call to the server is not working.')
}
});
お役に立てれば。ハッピーコード!:P
alehoの回答に同意して、ここに完全な例を示します。それは魅力のように機能し、超シンプルです。
コントローラーコード
[HttpGet]
public async Task<ActionResult> ChildItems()
{
var client = TranslationDataHttpClient.GetClient();
HttpResponseMessage response = await client.GetAsync("childItems);
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
List<WorkflowItem> parameters = JsonConvert.DeserializeObject<List<WorkflowItem>>(content);
return Json(content, JsonRequestBehavior.AllowGet);
}
else
{
return new HttpStatusCodeResult(response.StatusCode, response.ReasonPhrase);
}
}
}
ビューのJavaScriptコード
var url = '@Html.Raw(@Url.Action("ChildItems", "WorkflowItemModal")';
$.ajax({
type: "GET",
dataType: "json",
url: url,
contentType: "application/json; charset=utf-8",
success: function (data) {
// Do something with the returned data
},
error: function (xhr, status, error) {
// Handle the error.
}
});
これが他の誰かを助けることを願っています!
クライアント側でajax呼び出しからのエラーを処理するには、ajax呼び出しのerror
オプションに関数を割り当てます。
デフォルトをグローバルに設定するには、http://api.jquery.com/jQuery.ajaxSetupで説明されている関数を使用できます 。