Val*_*Val 39 error-handling asp.net-mvc http httpresponse asp.net-mvc-2
我一整天都在努力在我的ASP.NET MVC 2应用程序中实现错误处理.我看过各种各样的技术,但都没有正常工作.我正在使用MVC2和.NET 4.0(在MVC3发布之前启动项目;我们将在发布初始版本后进行升级).
在这一点上,我将很乐意正确处理404和500错误 - 403(需要授权)也会很好,其次是各种其他特定的响应.现在,我得到所有404,全部500,全部302在404之前,或者全部302在500之前.
这是我的要求(应该非常接近HTTP的基本要求):
如果找不到资源,则抛出404,并显示包含所请求URL的特定于404的页面.不要返回像302这样的中间响应代码.理想情况下,保留请求的URL,而不是显示新的URL /Error/NotFound,但如果显示后者,请确保我们没有返回重定向响应来获取它.
如果发生内部服务器错误,则抛出500,并显示500特定错误,并指出出现了什么问题.同样,不要返回中间响应代码,理想情况下不要更改URL.
这是我认为的404:
/Content/non-existent-dir/non-existent-file.txt/non-existent-controller/Foo/666/Home/non-existent-action/666/Home/Login/non-existent-id这是我认为的500:
POST /User/New/new-user-name-too-long-for-db-column-constraint其中一些问题需要由特定的控制器或模型识别,然后控制器应抛出适当的HttpException.其余的应该更一般地处理.
对于404情况#2,如果找不到控制器,我尝试使用自定义ControllerFactory来抛出404.对于404#3案例,我试图使用自定义基本控制器来覆盖HandleUnknownAction并抛出404.
在这两种情况下,我在404之前得到302.而且,我从来没有得到500个错误; 如果我修改Web.config以在我的Web服务端点中输入拼写错误,我仍然得到302,然后404表示无法找到使用 Web服务的URL(控制器/操作).我还将请求的URL作为(不需要的)查询字符串参数获取:/Error/NotFound?aspxerrorpath=/Home/non-existent-action
这两种技术都来自http://www.niksmit.com/wp/?p=17(如何使用ASP.Net MVC获取正常的404(找不到页面)错误页面),来自http:// richarddingwall .名称/ 2008/08/17 /为基础的战略,为资源-404-错误-在-ASPNET-MVC /
如果在我的Web.config中<customErrors mode="On" defaultRedirect="~/Error/Unknown" redirectMode="ResponseRedirect" />,我得到了相应的响应代码,但我的错误控制器永远不会被调用.取出redirectMode属性可以获得MVC错误视图,但是介入302和更改的URL - 并且始终是相同的控制器(Unknown= 500;如果我将其更改为NotFound一切看起来像404).
以下是我已阅读并尝试实施的其他一些内容:
..以及一堆StackOverflow帖子.
在我看来,这种错误处理对于Web应用程序来说是非常基本的,并且MVC框架应该具有开箱即用的默认设置,并且让人们将其扩展为其他工作.也许他们会在将来的版本中做到这一点.在此期间,有人可以向我提供有关如何实施正确HTTP响应的全面详细信息吗?
Dar*_*rov 49
这是您可以使用的一种技术.定义ErrorsController将为错误页面提供服务的内容:
public class ErrorsController : Controller
{
public ActionResult Http404()
{
Response.StatusCode = 404;
return Content("404", "text/plain");
}
public ActionResult Http500()
{
Response.StatusCode = 500;
return Content("500", "text/plain");
}
public ActionResult Http403()
{
Response.StatusCode = 403;
return Content("403", "text/plain");
}
}
Run Code Online (Sandbox Code Playgroud)
然后在Global.asax您可以订阅Application_Error您可以记录异常并执行以下相应操作的事件ErrorsController:
protected void Application_Error(object sender, EventArgs e)
{
var app = (MvcApplication)sender;
var context = app.Context;
var ex = app.Server.GetLastError();
context.Response.Clear();
context.ClearError();
var httpException = ex as HttpException;
var routeData = new RouteData();
routeData.Values["controller"] = "errors";
routeData.Values["exception"] = ex;
routeData.Values["action"] = "http500";
if (httpException != null)
{
switch (httpException.GetHttpCode())
{
case 404:
routeData.Values["action"] = "http404";
break;
case 403:
routeData.Values["action"] = "http403";
break;
case 500:
routeData.Values["action"] = "http500";
break;
}
}
IController controller = new ErrorsController();
controller.Execute(new RequestContext(new HttpContextWrapper(context), routeData));
}
Run Code Online (Sandbox Code Playgroud)
而现在剩下的就是开始抛出适当的例外:
public class HomeController : Controller
{
public ActionResult Index()
{
throw new HttpException(404, "NotFound");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16046 次 |
| 最近记录: |