Выбрасывание HttpException всегда отправляет обратно ошибку HTTP 500?
Я пытаюсь выбросить код ошибки HTTP 403 на клиенте. Я читал, что HttpException - самый чистый способ выполнить это, но он не работает для меня. Я исключаю исключение из такой страницы:
throw new HttpException(403,"You must be logged in to access this resource.");
Однако это приведет только к стандартной трассировке стека ASP.Net(с ошибкой 500), когда CustomErrors выключен. Если CustomErrors включен, то это не будет перенаправляться на страницу, на которую у меня установлена настройка, когда возникает ошибка 403. Должен ли я забыть о HttpException и вместо этого установить все HTTP-коды? Как это исправить?
Собственная часть ошибок моего Web.Config такова:
<customErrors mode="On" defaultRedirect="GenericErrorPage.html">
<error statusCode="403" redirect="Forbidden.html" />
</customErrors>
Вместо того, чтобы получать Forbidden.html, я получу GenericErrorPage.html
Ответы
Ответ 1
На самом деле я создал свой собственный отличный класс, чтобы исправить эту проблему. Он не обрабатывает все, и я не уверен, что он хорошо играет с MVC, но он работает для моего использования. В принципе, вместо того, чтобы полагаться на ASP.Net для вывода правильной страницы ошибки и кода ошибки, она очистит ошибку, а затем выполнит передачу на стороне сервера и отобразит соответствующую страницу ошибки Web.Config. Он также распознает режим customErrors и соответственно реагирует.
public static class CustomErrorsFixer
{
static public void HandleErrors(HttpContext Context)
{
if(RunIt(Context)==false){
return;
}
HttpException ex = Context.Error as HttpException;
if(ex==null){
try{
ex=Context.Error.InnerException as HttpException;
}catch{
ex=null;
}
}
if (ex != null){
Context.Response.StatusCode = ex.GetHttpCode();
}else{
Context.Response.StatusCode = 500;
}
Context.ClearError();
Context.Server.Transfer(GetCustomError(Context.Response.StatusCode.ToString()));
HttpContext.Current.Response.End();
}
static protected string GetCustomError(string code)
{
CustomErrorsSection section = ConfigurationManager.GetSection("system.web/customErrors") as CustomErrorsSection;
if (section != null)
{
CustomError page = section.Errors[code];
if (page != null)
{
return page.Redirect;
}
}
return section.DefaultRedirect;
}
static protected bool RunIt(HttpContext context){
CustomErrorsSection section = ConfigurationManager.GetSection("system.web/customErrors") as CustomErrorsSection;
switch(section.Mode){
case CustomErrorsMode.Off:
return false;
case CustomErrorsMode.On:
return true;
case CustomErrorsMode.RemoteOnly:
return !(context.Request.UserHostAddress=="127.0.0.1");
default:
return true;
}
}
}
И затем, чтобы активировать его, просто добавьте маленькую вещь в Global.asax
protected virtual void Application_Error (Object sender, EventArgs e)
{
CustomErrorsFixer.HandleErrors(Context);
}
Ответ 2
Вам необходимо переопределить ошибку приложения следующим образом:
protected void Application_Error()
{
var exception = Server.GetLastError();
var httpException = exception as HttpException;
Response.Clear();
Server.ClearError();
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 403:
routeData.Values["action"] = "Http403";
break;
case 404:
routeData.Values["action"] = "Http404";
break;
}
}
IController errorsController = new ErrorsController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
Затем вам нужно добавить errorsController:
public class ErrorsController : Controller
{
public ActionResult General(Exception exception)
{
ViewBag.ErrorCode = Response.StatusCode;
ViewBag.Message = "Error Happened";
//you should log your exception here
return View("Index");
}
public ActionResult Http404()
{
ViewBag.ErrorCode = Response.StatusCode;
ViewBag.Message = "Not Found";
return View("Index");
}
public ActionResult Http403()
{
ViewBag.Message = Response.StatusCode;
ViewBag.Message = "Forbidden";
return View("Index");
}
}
И последнее создайте представление для errorsController. Я создал только одно представление под индексом в Views/Errors/.
Надеюсь, что это было полезно.
Привет!
Ответ 3
Этот код включен в конфигурацию элемента /system.web файла Web.config:
<customErrors mode="On">
<error statusCode="403" redirect="~/errors/Forbidden.aspx"/>
</customErrors>
Мне удалось работать так, как ожидалось.
Вы можете найти хороший учебник с примерами (пример 3 является правильным) здесь:
http://aspnetresources.com/articles/CustomErrorPages
Или вы можете использовать Response.Status для этого:
Asp Classic возвращает определенный код состояния http