Я хочу вернуть статус HTTP 404
, если моему контроллеру переданы недопустимые аргументы. Например, если у меня есть контроллер, который выглядит так:
public ActionResult GetAccount(int id)
{
...
}
Тогда я хочу вернуть 404
, если встречаются такие URL-адреса:
/GetAccount /GetAccount/notanumber
т.е.Я хочу перехватить выброшенное ArgumentException
.
Я знаю, что могу использовать тип, допускающий значение NULL:
public ActionResult GetAccount(int? id)
{
if(id == null) throw new HttpException(404, "Not found");
}
Но это довольно неприятно и однообразно.
Я надеялся, что смогу добавить это в свои контроллеры, где это необходимо:
[HandleError(View="Error404", ExceptionType = typeof(ArgumentException))]
public class AccountsController : Controller
{
public ActionResult GetAccount(int id)
{
...
}
}
Но, похоже, это не работает.
Я видел этот пост и этот ответ , который почти решает мою проблему:
В этом ответе создается аннотация BaseController , из которой вы получаете все другие ваши контроллеры из:
public abstract class MyController : Controller
{
#region Http404 handling
protected override void HandleUnknownAction(string actionName)
{
// If controller is ErrorController dont 'nest' exceptions
if (this.GetType() != typeof(ErrorController))
this.InvokeHttp404(HttpContext);
}
public ActionResult InvokeHttp404(HttpContextBase httpContext)
{
IController errorController = ObjectFactory.GetInstance();
var errorRoute = new RouteData();
errorRoute.Values.Add("controller", "Error");
errorRoute.Values.Add("action", "Http404");
errorRoute.Values.Add("url", httpContext.Request.Url.OriginalString);
errorController.Execute(new RequestContext(
httpContext, errorRoute));
return new EmptyResult();
}
#endregion
}
Это отлично работает при обработке неизвестных действий с 404
, но не позволяет мне обрабатывать недопустимые данные как 404
.
Могу ли я безопасно переопределить Controller.OnException (ExceptionContext filterContext)
следующим образом:
protected override void OnException(ExceptionContext filterContext)
{
if(filterContext.Exception.GetType() == typeof(ArgumentException))
{
filterContext.ExceptionHandled = true;
this.InvokeHttp404(filterContext.HttpContext);
}
else
{
base.OnException(filterContext);
}
}
На первый взгляд кажется, что это работает, но сохраняются ли у меня какие-либо проблемы из-за этого?
Это семантически правильное действие?