How can I end the response and send the 404 HTTP code back?

I am using factory lock windsor to create an object based on the request url.

Something like:

public FooViewModel Get() { if (HttpContext.Current == null) { return new FooViewModel(); } var currentContext = new HttpContextWrapper(HttpContext.Current); // resolve actual view model. 

In some cases, I really want to reset 404 and stop the request, currently similar:

  throw new HttpException(404, "HTTP/1.1 404 Not Found"); currentContext.Response.End(); 

However, the request does not end, and it still gets into action and tries to resolve the view?

My controller will look something like this:

 public class HomeController : Controller { public FooViewModel Foo { get; set; } public ActionResult Index() { ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; return View(); } 

I think this is all wrong? Or is there a way I can achieve this?

Is the alternative I was thinking of an action attribute to check the status of the Foo property?

+7
source share
2 answers

I think the approach of using an action filter could achieve what you want:

 public class RequiresModelAttribute : ActionFilterAttribute { private readonly string _modelName; public RequiresModelAttribute(string modelName) { _modelName = modelName; } public override void OnActionExecuting(ActionExecutingContext filterContext) { var property = filterContext.Controller.GetType().GetProperty(_modelName); var model = property.GetValue(filterContext.Controller); if (model == null) { filterContext.Result = new HttpStatusCodeResult(404); } } } 

Then on your controller you can:

 public class HomeController : Controller { public FooViewModel Foo { get; set; } [RequiresModel("Foo")] public ActionResult Index() { ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; return View(); } } 

Edit: perhaps using a global filter to honor any running HttpExceptions?

 public class HonorHttpExceptionAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var httpException = filterContext.HttpContext.AllErrors.FirstOrDefault(x => x is HttpException) as HttpException; if (httpException != null) { filterContext.Result = new HttpStatusCodeResult(httpException.GetHttpCode()); } } } 

Then in Global.asax:

  public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); filters.Add(new HonorHttpExceptionAttribute()); } 
+6
source

Another option is to override OnException on the controller.

  public ActionResult Index() { ViewBag.Message = "Welcome to ASP.NET MVC!"; Get(); return View(); } public int Get() { throw new HttpException(404, "HTTP/1.1 404 Not Found"); // we don't need end the response here, we need go to result step // currentContext.Response.End(); } protected override void OnException(ExceptionContext filterContext) { base.OnException(filterContext); if (filterContext.Exception is HttpException) { filterContext.Result = this.HttpNotFound(filterContext.Exception.Message); } } 
+2
source

All Articles