如何从ASP.NET MVC应用程序返回404响应?

时间:2009-12-25 17:13:25

标签: asp.net-mvc

我有一个Controller,它从数据库中提取图像,重新调整大小,将结果缓存在磁盘上,并将图像作为Content()结果吐出。

最近我在我的网站上添加了对“Scrape-buster”代码的支持。也就是说,我将每个图像附加的唯一代码的哈希加上一些盐,并将该哈希的前几个字符传递给用户,以便在检索期间进行确认。这使我可以防止人们从网站上刮掉每一张图片。 (没有登录,也刮掉HTML,就是这样。)

无论如何,如果ScrapeBuster代码不正确,我想从我的控制器返回404错误。是否有内置的方法来执行此操作,或者我是否正在构建自定义ActionResult

5 个答案:

答案 0 :(得分:6)

最简单(可能不是最干净)的方法是抛出HttpException

public static void Throw404()
{
    throw new HttpException(404, "The resource cannot be found");
}

您应该确保调用堆栈中没有人捕获异常。这样,输出看起来就像普通的ASP.NET黄色死亡屏幕404.

更简洁的方法是返回自定义结果:

public sealed class HttpNotFoundResult : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        context.HttpContext.Response.StatusCode = 404;
    }
}

答案 1 :(得分:5)

为什么不使用内置的HttpNotFoundResult?

  

返回HttpNotFound();

答案 2 :(得分:2)

您可以通过返回HttpUnauthorizedResult发送403。这可以说是一个更正确的响应,因为URL有效,但不包含“授权”信息。如果您的网站配置正确,它还可以将它们重定向到您的登录页面。

答案 3 :(得分:1)

public class NotFoundViewResult : ViewResult
{
    public ViewResultNotFound()
    {
        ViewName = "NotFound";
    }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.TrySkipIisCustomErrors = true;
        context.HttpContext.Response.StatusCode = 404;

        base.ExecuteResult(context);
    }
}

~/Views/Shared文件夹

中创建NotFound View

答案 4 :(得分:0)

谢谢大家,这是我从你的答案中得出的结论:

public static class HttpErrorResultHelper
{
    public static HttpErrorResult HttpError(this Controller controller, int statusCode)
    {
        return new HttpErrorResult
        {
            StatusCode = statusCode
        };
    }

    public static HttpErrorResult HttpError(this Controller controller, int statusCode, ActionResult chainedAction)
    {
        return new HttpErrorResult
        {
            StatusCode = statusCode,
            ChainedAction = chainedAction,
        };
    }
}

public sealed class HttpErrorResult : ActionResult
{
    public int StatusCode { get; set; }

    public ActionResult ChainedAction { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        context.HttpContext.Response.TrySkipIisCustomErrors = true;
        context.HttpContext.Response.StatusCode = this.StatusCode;

        if (this.ChainedAction != null)
        {
            ChainedAction.ExecuteResult(context);
        }
    }
}

这样做的前提是将状态代码添加到响应的前面,同时仍然允许您发送实际的视图结果。

this.HttpError(404, this.View("NotFound"));