繁体   English   中英

如何在asp.net mvc中处理'查找未找到'InvalidOperationException?

[英]How to handle 'View not found' InvalidOperationException in asp.net mvc?

我有一个asp.net mvc 1.0站点,它提供来自2级层次结构/类别/文章的一些内容

当事情正常工作时,文章会映射到视图并呈现视图。 但是,当url符合路由条件但视图不存在时,会引发异常,我无法陷入Controller操作。

路由:

routes.MapRoute(
  "Article",
  "{category}/{article}.aspx",
  new { controller = "MyController", action = "Article" }
);

MyController动作:

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'或其主文件。 搜索了以下位置:〜/ Views / my-category / my-article-with-long-name.aspx

我可以在global.asax.cs中的Application_Error()方法中捕获错误,但是:

  1. 不知道如何从那里重定向到错误视图
  2. 想知道是否有一个更接近异常的地方。

xandy,Greg,我感谢你的回答。 本文( aspnet mvc中基于资源的404错误的策略 )帮助我以一种非常干净的方式推导出我正在寻找的解决方案。 我需要做的就是覆盖Controller.OnException。 由于我只有一个控制器,我需要行为,我只需要覆盖该控制器中的OnException。

话虽这么说,我的解决方案治疗的症状不是疾病,正如你们所建议的那样,最好在调用此方法之前检查文件是否存在。查看路径。

这是我用来治疗症状的代码:)

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路径。

有一个合适的地方来处理这个问题。 如果您实现自己的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返回友好消息。

我认为检查视图是否存在的最佳位置是在控制器内。 如果封装视图的构造函数不起作用,那么它可能是ASP.net推迟构造函数外的View的实例化(不确定它是否)。

但您可能尝试的一件事是手动检查并查看路径是否存在,使用Server.MapPath()获取绝对文件路径并检查它是否存在。

我只会返回一个默认视图,也许404响应是合适的。 当然要做到这一点,你需要稍微改变你的架构。

AFAIK您需要有一些代码来检查文件是否存在,如果您不想要默认的框架行为,就像在ASPX文件中一样。 您可能应该使用ResolveURL或Url.Content来解析应用程序路径中的路径。

作为一个注释,通常,使您的域(文件名)暴露给世界并不完全安全。 如果ASPX只是数据,那么您应该将文本放入数据库或普通的非可执行文本文件中。 如果您正在构建某种CMS(即您真的想要一种'安装'功能),那么您可以考虑使用ASPX视图来包含部分视图来封装ASP.NET代码块。

至于进入404页面, 这个答案可能有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM