2009-12-25 3 views
3

У меня есть контроллер, который извлекает изображения из базы данных, изменяет размеры, кэширует результат на диске и выплескивает изображение как результат Content().Как я могу вернуть ответ 404 от приложения ASP.NET MVC?

Недавно я добавил поддержку кода «Scrape-buster» на моем сайте. То есть, я беру хэш уникального кода, прикрепленного к каждому изображению плюс некоторую соль, и передаю пользователю несколько первых символов этого хэша для подтверждения во время поиска. Это позволяет мне не допустить, чтобы люди соскабливали каждое изображение с сайта. (Без входа в систему и соскабливания HTML, а именно.)

В любом случае, если код ScrapeBuster неверен, я хотел бы вернуть ошибку 404 с моего контроллера. Есть ли встроенный способ сделать это, или я смотрю на создание пользовательского ActionResult?

ответ

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; 
    } 
} 
+2

HttpNotFoundResult теперь присутствует в System.Web.MVC - вам не нужно писать свой собственный –

2

Вы можете отправить 403, возвращая HttpUnauthorizedResult. Это, возможно, более правильный ответ, поскольку URL-адрес действителен, но не содержит информацию о «авторизации». Если ваш сайт будет настроен правильно, он также будет иметь дополнительное преимущество для перенаправления их на вашу страницу входа.

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); 
    } 
} 

И создать NotFound Просмотреть в ~/Views/Shared папке

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")); 
5

Почему бы просто не использовать встроенный HttpNotFoundResult?

возвращение HttpNotFound();

+0

Я хочу показать конкретное представление, включая код ответа 404. –

Смежные вопросы