代码之家  ›  专栏  ›  技术社区  ›  BC.

在ASP.NET MVC控制器结果中设置HTTP状态不会呈现视图

  •  6
  • BC.  · 技术社区  · 15 年前

    我有一个自定义的ActionResult来返回某些HTTP错误,比如NotFoundResult和ForbiddenResult,它们都是从ViewResult派生的。

    我将它们用于一些实例,如在操作过程中数据库中找不到实体时使用404进行短路操作。

    在这些结果对象中,我将HTTP状态设置为适当的数字。执行此操作时,这些ViewResults引用的视图不会渲染。我必须将状态保留为200 OK才能呈现我的视图。

    如何在ASP.NET MVC 2.0中设置适当的状态并呈现视图?

    1 回复  |  直到 15 年前
        1
  •  8
  •   Darin Dimitrov    15 年前

    我有一个自定义的ActionResult 返回某些HTTP错误,如 NotFoundResult和ForbiddenResult, 它们都源于ViewResult。

    请允许我向您建议另一种错误处理方法:

    首先创建错误控制器和相应的视图:

    public class ErrorController : Controller
    {
        public ActionResult General()
        {
            return View();
        }
    
        public ActionResult HttpError404()
        {
            return View();
        }
    
        public ActionResult HttpError500()
        {
            return View();
        }
    }
    

    Global.asax 定义 Application_Error

    protected void Application_Error(object sender, EventArgs e)
    {
        var exception = Server.GetLastError();
        // TODO: Log the exception with your favorite logging framework
    
        Response.Clear();
        var httpException = exception as HttpException;
    
        var routeData = new RouteData();
        // Take the ErrorController
        routeData.Values.Add("controller", "error");
    
        if (httpException == null)
        {
            // Use the General action for any unhandled error
            routeData.Values.Add("action", "general");
        }
        else
        {
            switch (httpException.GetHttpCode())
            {
                case 404:
                    routeData.Values.Add("action", "httpError404");
                    break;
                case 500:
                    routeData.Values.Add("action", "httpError500");
                    break;
                default:
                    routeData.Values.Add("action", "general");
                    break;
            }
        }
    
        // Add the exception to route data so that the error controller 
        // could use it with RouteData.Values["error"]
        routeData.Values.Add("error", exception);
    
        Server.ClearError();
        IController errorController = new ErrorController();
        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    }
    

    最后抛出适当的异常:

    public class HomeController: Controller
    {
        public ActionResult Index(int id)
        {
            var model = _repository.GetModel(id);
            if (model == null)
            {
                throw new HttpException(404, "Model not found with id = " + id);
            }
            return View(model);
        }
    }