Dav*_*ace 40 asp.net asp.net-mvc-3
每次从控制器返回HttpNotFoundResult时,有没有办法返回相同的视图?你如何指定这个视图?我猜测在web.config中配置404页面可能有效,但我想知道是否有更好的方法来处理这个结果.
编辑/跟进:
我最后使用了这个问题的第二个答案中找到的解决方案,并对ASP.Net MVC 3进行了一些微调,以处理我的404:如何正确处理ASP.Net MVC中的404?
Dar*_*rov 65
HttpNotFoundResult不呈现视图.它只是将状态代码设置为404并返回一个空结果,这对AJAX之类的东西很有用,但是如果你想要一个自定义404错误页面,你可以throw new HttpException(404, "Not found")在web.config中自动呈现配置的视图:
<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="/Http404.html" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)
Ger*_*mán 17
此解决方案结合了IResultFilter和IExceptionFilter来捕获抛出的HttpException或从操作中返回HttpStatusCodeResult.
public class CustomViewForHttpStatusResultFilter: IResultFilter, IExceptionFilter
{
string viewName;
int statusCode;
public CustomViewForHttpStatusResultFilter(HttpStatusCodeResult prototype, string viewName)
: this(prototype.StatusCode, viewName) {
}
public CustomViewForHttpStatusResultFilter(int statusCode, string viewName) {
this.viewName = viewName;
this.statusCode = statusCode;
}
public void OnResultExecuted(ResultExecutedContext filterContext) {
HttpStatusCodeResult httpStatusCodeResult = filterContext.Result as HttpStatusCodeResult;
if (httpStatusCodeResult != null && httpStatusCodeResult.StatusCode == statusCode) {
ExecuteCustomViewResult(filterContext.Controller.ControllerContext);
}
}
public void OnResultExecuting(ResultExecutingContext filterContext) {
}
public void OnException(ExceptionContext filterContext) {
HttpException httpException = filterContext.Exception as HttpException;
if (httpException != null && httpException.GetHttpCode() == statusCode) {
ExecuteCustomViewResult(filterContext.Controller.ControllerContext);
// This causes ELMAH not to log exceptions, so commented out
//filterContext.ExceptionHandled = true;
}
}
void ExecuteCustomViewResult(ControllerContext controllerContext) {
ViewResult viewResult = new ViewResult();
viewResult.ViewName = viewName;
viewResult.ViewData = controllerContext.Controller.ViewData;
viewResult.TempData = controllerContext.Controller.TempData;
viewResult.ExecuteResult(controllerContext);
controllerContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以注册此过滤器,指定要为其显示自定义视图的HttpException的http状态代码或具体的HttpStatusCodeResult.
GlobalFilters.Filters.Add(new CustomViewForHttpStatusResultFilter(new HttpNotFoundResult(), "Error404"));
// alternate syntax
GlobalFilters.Filters.Add(new CustomViewForHttpStatusResultFilter(404, "Error404"));
Run Code Online (Sandbox Code Playgroud)
它处理在动作中抛出或返回的异常和HttpStatusCodeResult.它不会处理在MVC选择合适的操作和控制器之前发生的错误,例如:
要处理这些类型的NotFound错误,请将此解决方案与stackoverflow中的其他解决方案结合使用.
Cal*_*aNN 14
@Darin Dimitrov HttpNotFoundResult实际返回空结果的有用信息.
经过一番研究.对于解决办法MVC 3这里是推导出所有的HttpNotFoundResult,HttpUnauthorizedResult,HttpStatusCodeResult类和实现新的(重写它)HttpNotFound在()方法BaseController.
最佳做法是使用基本控制器,以便"控制"所有派生控制器.
我创建了一个新HttpStatusCodeResult类,不是通过指定属性来派生,ActionResult而是通过ViewResult渲染视图或任何View你想要的ViewName.我按照原始HttpStatusCodeResult设置HttpContext.Response.StatusCode,HttpContext.Response.StatusDescription然后base.ExecuteResult(context)将呈现合适的视图,因为我再次得出ViewResult.这很简单吗?希望这将在MVC核心中实现.
看到我的BaseController吼叫:
using System.Web;
using System.Web.Mvc;
namespace YourNamespace.Controllers
{
public class BaseController : Controller
{
public BaseController()
{
ViewBag.MetaDescription = Settings.metaDescription;
ViewBag.MetaKeywords = Settings.metaKeywords;
}
protected new HttpNotFoundResult HttpNotFound(string statusDescription = null)
{
return new HttpNotFoundResult(statusDescription);
}
protected HttpUnauthorizedResult HttpUnauthorized(string statusDescription = null)
{
return new HttpUnauthorizedResult(statusDescription);
}
protected class HttpNotFoundResult : HttpStatusCodeResult
{
public HttpNotFoundResult() : this(null) { }
public HttpNotFoundResult(string statusDescription) : base(404, statusDescription) { }
}
protected class HttpUnauthorizedResult : HttpStatusCodeResult
{
public HttpUnauthorizedResult(string statusDescription) : base(401, statusDescription) { }
}
protected class HttpStatusCodeResult : ViewResult
{
public int StatusCode { get; private set; }
public string StatusDescription { get; private set; }
public HttpStatusCodeResult(int statusCode) : this(statusCode, null) { }
public HttpStatusCodeResult(int statusCode, string statusDescription)
{
this.StatusCode = statusCode;
this.StatusDescription = statusDescription;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
context.HttpContext.Response.StatusCode = this.StatusCode;
if (this.StatusDescription != null)
{
context.HttpContext.Response.StatusDescription = this.StatusDescription;
}
// 1. Uncomment this to use the existing Error.ascx / Error.cshtml to view as an error or
// 2. Uncomment this and change to any custom view and set the name here or simply
// 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
//this.ViewName = "Error";
this.ViewBag.Message = context.HttpContext.Response.StatusDescription;
base.ExecuteResult(context);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
要像你这样在你的行动中使用:
public ActionResult Index()
{
// Some processing
if (...)
return HttpNotFound();
// Other processing
}
Run Code Online (Sandbox Code Playgroud)
并在_Layout.cshtml(如母版页)
<div class="content">
@if (ViewBag.Message != null)
{
<div class="inlineMsg"><p>@ViewBag.Message</p></div>
}
@RenderBody()
</div>
Run Code Online (Sandbox Code Playgroud)
此外,您可以像我在代码中注释的那样使用自定义视图Error.shtml或创建新视图NotFound.cshtml,您可以为状态描述和其他解释定义视图模型.
| 归档时间: |
|
| 查看次数: |
34356 次 |
| 最近记录: |