Хорошо, поэтому краткий ответ ( tl; dr ) заключается в том, что вам нужно обрабатывать все исключения в чистом и организованном порядке.И это НЕ для того, чтобы делать это индивидуально в каждом действии контроллера, как я (как фиктивный) изначально планировал.
Вместо этого я подключил свой метод Global Application_Error
для обработки всех ошибок и пробивал ихк контроллеру ошибок с одним index
действием.
private void Application_Error()
{
// setup the route to Send the error to
var routeData = new RouteData();
routeData.Values.Add("action", "Index");
// Execute the ErrorController instead of the intended controller
IController errorController = new Controllers.ErrorController();
errorController.Execute(new RequestContext(new HttpContextWrapper(this.Context), routeData));
// After the controller executes, clear the error.
this.Server.ClearError();
}
Мой контроллер ошибок довольно прост.По сути, он принимает последнюю ошибку и передает соответствующие данные клиенту (в моем случае сериализует их как JsonP).
public class ErrorController : Controller
{
public JsonpResult Index()
{
var lastError = Server.GetLastError();
var message = lastError.Message;
int statusCode;
// If the lastError is a System.Exception, then we
// need to manually set the Http StatusCode.
if (lastError.GetType() == typeof(System.Exception))
{
statusCode = 500;
}
else
{
var httpException = (HttpException)this.Server.GetLastError();
statusCode = httpException.GetHttpCode();
}
// Set the status code header.
this.Response.StatusCode = statusCode;
// create a new ErrorsModel that can be past to the client
var err = new ErrorsModel()
{
ErrorMessage = message,
StatusCode = statusCode
};
return this.Jsonp(err, false);
}
}
Теперь, чтобы добавить немного надежности в мое приложение, я создал пользовательскийExceptions
, которые соответствуют Http StatusCodes.
public sealed class UnauthorizedException : HttpException
{
/// <summary>
/// Similar to 403 Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided
/// </summary>
public UnauthorizedException(string message) : base((int)StatusCode.Unauthorized, message) { }
}
Теперь я могу генерировать исключения во всем приложении, где это применимо, и все они будут обрабатываться и отправляться клиенту простым в управлении способом.
Вот пример выброса одной из упомянутых ошибок.
if (!User.Identity.IsAuthenticated)
throw new UnauthorizedException("You are not authorized");