控制器动作:
public ActionResult Foo()
{
// Obviously DoSomething could throw but if we start
// trying and catching on every single thing that could throw
// our controller actions will resemble some horrible plumbing code more
// than what they normally should resemble: a.k.a being slim and focus on
// what really matters which is fetch a model and pass to the view
// Here you could return any type of view you like: JSON, HTML, XML, CSV, PDF, ...
var model = DoSomething();
return PartialView(model);
}
然后我们为我们的应用程序定义一个全局错误处理程序:
protected void Application_Error(object sender, EventArgs e)
{
var exception = Server.GetLastError();
var httpException = exception as HttpException;
Response.Clear();
Server.ClearError();
if (new HttpRequestWrapper(Request).IsAjaxRequest())
{
// Some error occurred during the execution of the request and
// the client made an AJAX request so let's return the error
// message as a JSON object but we could really return any JSON structure
// we would like here
Response.StatusCode = 500;
Response.ContentType = "application/json";
Response.Write(new JavaScriptSerializer().Serialize(new
{
errorMessage = exception.Message
}));
return;
}
// Here we do standard error handling as shown in this answer:
// http://stackoverflow.com/q/5229581/29407
var routeData = new RouteData();
routeData.Values["controller"] = "Errors";
routeData.Values["action"] = "General";
routeData.Values["exception"] = exception;
Response.StatusCode = 500;
if (httpException != null)
{
Response.StatusCode = httpException.GetHttpCode();
switch (Response.StatusCode)
{
case 404:
routeData.Values["action"] = "Http404";
break;
case 500:
routeData.Values["action"] = "Http500";
break;
}
}
IController errorsController = new ErrorsController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
下面是全局错误处理程序中使用的 ErrorsController 的样子。或许我们可以为 404 和 500 动作定义一些自定义视图:
public class ErrorsController : Controller
{
public ActionResult Http404()
{
return Content("Oops 404");
}
public ActionResult Http500()
{
return Content("500, something very bad happened");
}
}
然后我们可以为所有 AJAX 错误订阅一个全局错误处理程序,这样我们就不必为所有 AJAX 请求重复这个错误处理代码,但如果我们愿意,我们可以重复它:
$('body').ajaxError(function (evt, jqXHR) {
var error = $.parseJSON(jqXHR.responseText);
alert('An error occured: ' + error.errorMessage);
});
最后,我们向控制器操作发出 AJAX 请求,希望在这种情况下返回 HTML 部分:
$.ajax({
url: 'whatever/trevor',
success: function (html) {
$container.html(html);
}
});