私がやろうとしているのは、カスタム エラーを asp.net mvc4 コントローラーから jquery.ajax() 呼び出しに渡すことです。そこで、カスタム エラー フィルターを作成しました。
public class FormatExceptionAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult()
{
ContentType = "application/json",
Data = new
{
name = filterContext.Exception.GetType().Name,
message = filterContext.Exception.Message,
callstack = filterContext.Exception.StackTrace
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
else
{
base.OnException(filterContext);
}
}
}
そして、次を実行してグローバルフィルターとして登録しました。
GlobalFilters.Filters.Add(new FormatExceptionAttribute());
mvc4 ビューで定義された ajax 呼び出しの下 (タスクは "/MyController/MyAction/" のような文字列であることに注意してください):
function loadData(task) {
ajax({
url: task,
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8"
}).then(function (data) {
$(data).map(function (i, item) {
addNewElement(item);
})
},
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');
}
});
};
したがって、Mycontroller の MyAction は次のようになります。
[HttpPost]
public ActionResult MyAction()
{
try
{
var dataCollection = (dynamic)null;
using (ConfigContext context = new ConfigContext())
{
dataCollection = context.MyItems.Where(i=> i.TypeId == 1).AsEnumerable().OrderBy(k => k.Name).Select(w => new
{
Alias = string.Format("{0}-{1}", Resources.Constants.Prefix, w.Id),
Name = w.Name,
Desc = w.Desc
}).ToArray();
}
return Json(dataCollection);
}
catch (Exception ex)
{
// I want to return ex.Message to the jquery.ajax() call
JsonResult jsonOutput = Json(
new
{
reply = new
{
status = "Failed in MyAction.",
message = "Error: " + ex.Message
}
});
return jsonOutput;
}
}
何らかの理由で、jquery.ajax() 呼び出しで、次を使用して json に変換しようとすると、コントローラー (サーバー側) および jquery.ajax() によって送信された ex.message エラーが発生しません。
var json = $.parseJSON(xhr.responseText);
json の結果ではないという例外がスローされるため、jquery.ajax では catch 本文に入力されます。
} catch (e) {
alert('something bad happened');
}
だから私がやりたいことは次のとおりです。
- コントローラーから jquery.ajax() 呼び出しに ex.message を返します。
- さらに、global.asax.cs でグローバル フィルターとして示されている上記のカスタム エラー フィルターを登録する代わりに、ajax 呼び出しによって呼び出される特定のコントローラー/アクションにのみ適用したいと思います。
- また (別のスレッドを開くほうがよいかもしれません)、コントローラーの MyAction の文字列連結 (String.format) は、IIS の既定の Web サイトで Web アプリをアプリケーションとして展開/公開すると例外をスローしますが、それは別の Web サイトとして展開する場合は正常に動作します (エラーは発生しません)。SQL Server コンパクト エディション SQLCe 組み込みを使用しています。私の知る限り、連結はサポートされていませんが、AsEnumerable() を適用することでこれを解決しました。Web アプリを別の Web サイトとして展開する場合は機能しますが、既定の Web サイトでアプリケーションとして展開する場合は機能しません。ここに何かアイデアはありますか?