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

时间:2010-07-01 16:26:38

标签: asp.net-mvc http-status-codes

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

如果在行动过程中未在数据库中找到实体,我会将它们用于像404这样的短路操作。

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

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

1 个答案:

答案 0 :(得分:8)

  

我有自定义的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);
    }
}