code_junkie

What is the proper way to send an HTTP 404 response from an ASP.NET MVC action

Nov 14th, 2011
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.78 KB | None | 0 0
  1. public class HomeController : Controller
  2. {
  3. public ActionResult Index()
  4. {
  5. return new HttpNotFoundResult("This doesn't exist");
  6. }
  7. }
  8.  
  9. using System;
  10. using System.Net;
  11. using System.Web;
  12. using System.Web.Mvc;
  13.  
  14. namespace YourNamespaceHere
  15. {
  16. /// <summary>An implementation of <see cref="ActionResult" /> that throws an <see cref="HttpException" />.</summary>
  17. public class HttpNotFoundResult : ActionResult
  18. {
  19. /// <summary>Initializes a new instance of <see cref="HttpNotFoundResult" /> with the specified <paramref name="message"/>.</summary>
  20. /// <param name="message"></param>
  21. public HttpNotFoundResult(String message)
  22. {
  23. this.Message = message;
  24. }
  25.  
  26. /// <summary>Initializes a new instance of <see cref="HttpNotFoundResult" /> with an empty message.</summary>
  27. public HttpNotFoundResult()
  28. : this(String.Empty) { }
  29.  
  30. /// <summary>Gets or sets the message that will be passed to the thrown <see cref="HttpException" />.</summary>
  31. public String Message { get; set; }
  32.  
  33. /// <summary>Overrides the base <see cref="ActionResult.ExecuteResult" /> functionality to throw an <see cref="HttpException" />.</summary>
  34. public override void ExecuteResult(ControllerContext context)
  35. {
  36. throw new HttpException((Int32)HttpStatusCode.NotFound, this.Message);
  37. }
  38. }
  39. }
  40. // By Erik van Brakel, with edits from Daniel Schaffer :)
  41.  
  42. /// <summary>
  43. /// returns our standard page not found view
  44. /// </summary>
  45. protected ViewResult PageNotFound()
  46. {
  47. Response.StatusCode = 404;
  48. return View("PageNotFound");
  49. }
  50.  
  51. public ActionResult ShowUserDetails(int? id)
  52. {
  53. // make sure we have a valid ID
  54. if (!id.HasValue) return PageNotFound();
  55.  
  56. throw new HttpException(404, "Are you sure you're in the right place?");
  57.  
  58. using System.Web;
  59. using System.Web.Mvc;
  60.  
  61. namespace YourNamespace.Controllers
  62. {
  63. public class BaseController : Controller
  64. {
  65. public BaseController()
  66. {
  67. ViewBag.MetaDescription = Settings.metaDescription;
  68. ViewBag.MetaKeywords = Settings.metaKeywords;
  69. }
  70.  
  71. protected new HttpNotFoundResult HttpNotFound(string statusDescription = null)
  72. {
  73. return new HttpNotFoundResult(statusDescription);
  74. }
  75.  
  76. protected HttpUnauthorizedResult HttpUnauthorized(string statusDescription = null)
  77. {
  78. return new HttpUnauthorizedResult(statusDescription);
  79. }
  80.  
  81. protected class HttpNotFoundResult : HttpStatusCodeResult
  82. {
  83. public HttpNotFoundResult() : this(null) { }
  84.  
  85. public HttpNotFoundResult(string statusDescription) : base(404, statusDescription) { }
  86.  
  87. }
  88.  
  89. protected class HttpUnauthorizedResult : HttpStatusCodeResult
  90. {
  91. public HttpUnauthorizedResult(string statusDescription) : base(401, statusDescription) { }
  92. }
  93.  
  94. protected class HttpStatusCodeResult : ViewResult
  95. {
  96. public int StatusCode { get; private set; }
  97. public string StatusDescription { get; private set; }
  98.  
  99. public HttpStatusCodeResult(int statusCode) : this(statusCode, null) { }
  100.  
  101. public HttpStatusCodeResult(int statusCode, string statusDescription)
  102. {
  103. this.StatusCode = statusCode;
  104. this.StatusDescription = statusDescription;
  105. }
  106.  
  107. public override void ExecuteResult(ControllerContext context)
  108. {
  109. if (context == null)
  110. {
  111. throw new ArgumentNullException("context");
  112. }
  113.  
  114. context.HttpContext.Response.StatusCode = this.StatusCode;
  115. if (this.StatusDescription != null)
  116. {
  117. context.HttpContext.Response.StatusDescription = this.StatusDescription;
  118. }
  119. // 1. Uncomment this to use the existing Error.ascx / Error.cshtml to view as an error or
  120. // 2. Uncomment this and change to any custom view and set the name here or simply
  121. // 3. (Recommended) Let it commented and the ViewName will be the current controller view action and on your view (or layout view even better) show the @ViewBag.Message to produce an inline message that tell the Not Found or Unauthorized
  122. //this.ViewName = "Error";
  123. this.ViewBag.Message = context.HttpContext.Response.StatusDescription;
  124. base.ExecuteResult(context);
  125. }
  126. }
  127. }
  128. }
  129.  
  130. public ActionResult Index()
  131. {
  132. // Some processing
  133. if (...)
  134. return HttpNotFound();
  135. // Other processing
  136. }
  137.  
  138. <div class="content">
  139. @if (ViewBag.Message != null)
  140. {
  141. <div class="inlineMsg"><p>@ViewBag.Message</p></div>
  142. }
  143. @RenderBody()
  144. </div>
  145.  
  146. public class HandleNotFoundAttribute : ActionFilterAttribute, IExceptionFilter
  147. {
  148. public void OnException(ExceptionContext filterContext)
  149. {
  150. var httpException = filterContext.Exception.GetBaseException() as HttpException;
  151. if (httpException != null && httpException.GetHttpCode() == (int)HttpStatusCode.NotFound)
  152. {
  153. filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; // Prevents IIS from intercepting the error and displaying its own content.
  154. filterContext.ExceptionHandled = true;
  155. filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.NotFound;
  156. filterContext.Result = new ViewResult
  157. {
  158. ViewName = "404",
  159. ViewData = filterContext.Controller.ViewData,
  160. TempData = filterContext.Controller.TempData
  161. };
  162. }
  163. }
  164. }
Add Comment
Please, Sign In to add comment