我有一个asp.net mvc 1.0站点,它提供来自2级层次结构的一些内容 /类别/条
当事情正常时,文章会映射到视图并呈现视图。但是,当url符合路由条件但视图不存在时,会引发异常,我无法捕获Controller操作。
路由:
routes.MapRoute(
"Article",
"{category}/{article}.aspx",
new { controller = "MyController", action = "Article" }
);
MyController Action:
public ActionResult Article(string category, string article)
{
string path = string.Format("~/Views/{0}/{1}.aspx", category, article);
ViewResult vr = View(path);
return vr;
}
但是,当找不到视图时,会生成System.InvalidOperationException
,我无法在Controller Action中捕获。
异常详细信息:System.InvalidOperationException:视图 '〜/ Views / my-category / my-article-with-long-name.aspx'或其主人 无法找到。搜索了以下位置: 〜/查看/我的类别/我的-物品与 - 长name.aspx
我可以在Application_Error()
中的global.asax.cs
方法中捕获错误,但是:
答案 0 :(得分:7)
话虽如此,我的解决方案是治疗症状而不是疾病,正如你们所建议的那样,最好在调用此方法之前检查文件是否存在。查看路径。
以下是我用来治疗症状的代码:)
protected override void OnException(ExceptionContext filterContext)
{
//InvalidOperationException is thrown if the path to the view
// cannot be resolved by the viewengine
if (filterContext.Exception is InvalidOperationException)
{
filterContext.ExceptionHandled = true;
filterContext.Result = View("~/Views/Error/NotFound.aspx");
filterContext.HttpContext.Response.StatusCode = 404;
}
base.OnException(filterContext);
}
我无法解决的一个问题是如何以干净的方式显示NotFound视图。它通常通过ErrorController NotFound Action访问。我不得不硬编码它的路径。我可以忍受这个,但想知道是否有可能没有HC路径。
答案 1 :(得分:3)
有一个合适的地方可以解决这个问题。如果您实现自己的ViewEngine,则可以覆盖" FileExists"方法
public class ViewEngine : RazorViewEngine
{
protected override bool FileExists(ControllerContext context, string path)
{
if(!base.FileExists(context, path))
throw new NotFoundException();
return true;
}
}
您只需要在Global.asax中注册视图引擎,就像这样,
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new ViewEngine());
在Application_Error中,您可以实现捕获NotFoundExceptions的处理程序,记录它们,然后通过执行ErrorController返回友好消息。
答案 2 :(得分:0)
我认为检查视图是否存在的最佳位置是在控制器内。如果封装视图的构造函数不起作用,则可能是ASP.net推迟构造函数外部的View实例化(不确定是否)。
但您可能尝试的一件事是手动检查并查看路径是否存在,使用Server.MapPath()获取绝对文件路径并检查它是否存在。
答案 3 :(得分:0)
我只会返回默认视图,也许404响应是合适的。当然要做到这一点,你需要稍微改变你的架构。
AFAIK您需要有一些代码来检查文件是否存在,如果您不想要默认的框架行为,就像在ASPX文件中一样。您可能应该使用ResolveURL or Url.Content来解析应用程序路径中的路径。
作为一个注释,通常情况下,将您的域名(文件名)暴露给世界并不完全安全。如果ASPX只是数据,那么您应该将文本放入数据库或普通的非可执行文本文件中。如果您正在构建某种CMS(即,您真的想要一种“安装”功能),那么您可以考虑使用ASPX视图来包含部分视图以封装ASP.NET代码块。
至于进入404页面,this answer可能有所帮助。