【问题标题】:How to access resources in ASP.NET Views folder?如何访问 ASP.NET Views 文件夹中的资源?
【发布时间】:2014-06-14 11:01:58
【问题描述】:

Views 文件夹中的资源是 CSS,View 中使用的图像,现在我知道它与它的含义不同,我们已经将所有内容都放在了 Contents 文件夹中,但我正在寻找更好的方法来管理它。

我们有一个非常大的 MVC 4,有很多区域,每个区域都有很多视图。为了维护所有内容,我们在内容文件夹中创建了类似的文件夹结构,以相应地分发 CSS 和图像。

但问题是,引用视图中的每个资源。跟踪变得困难,这里是文件夹结构。

  • 区域
    • 应用程序
      • 控制器
      • 查看次数
        • 项目
          • Search.cshtml
        • 用户
          • Account.cshtml
  • 内容
    • common.less
    • 应用程序
      • app.less
      • 一些按钮.png
      • projects.less
      • users.less

现在当我们有太多资源并且很难交叉引用时会出现问题,因为我们会更改用户界面,随着项目的增长会出现新的视图。

我想要以下格式的资源,

  • 区域
    • 应用程序
      • 控制器
      • 查看次数
        • 项目
          • Search.cshtml
          • search.less
          • 一些按钮.png
        • 用户
          • Account.cshtml
          • account.less
          • 一些按钮.png

我怎样才能轻松做到?

我的每个控制器都派生自一个通用 AppController,我们在其中验证用户身份验证和角色。我已经实现了 CustomActionInvoker 来查找如下视图。

private string defaultViewName = "";

protected virtual object GetDefaultViewModel() {
    return null;
}

public virtual ActionResult DefaultView() {

    try
    {
        var view = this.View(defaultViewName);
        if (view == null)
        {
            return HttpNotFound(defaultViewName + " View not found");
        }
        ViewBag.Title = defaultViewName;
    }
    catch
    {
        //Utils.Log(ex);
        //throw;
        return HttpNotFound(defaultViewName + " View not found");
    }            

    return View(defaultViewName, GetDefaultViewModel());
}

protected override IActionInvoker CreateActionInvoker()
{
    return new DefaultViewInvoker(base.CreateActionInvoker(), this);
}

internal class DefaultViewInvoker : ControllerActionInvoker {

    private IActionInvoker parent;
    private CastingWebController wc;

    internal DefaultViewInvoker(IActionInvoker parent, CastingWebController wc)
    {
        this.parent = parent;
        this.wc = wc;
    }

    protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
    {
        ActionDescriptor ad  = base.FindAction(controllerContext, controllerDescriptor, actionName);
        if (ad == null) {
            wc.defaultViewName = actionName;
            ad = base.FindAction(controllerContext, controllerDescriptor, "DefaultView");
        }
        return ad;
    }

}

这很好用,即使我们在控制器上没有操作方法,它也会分发 CSHTML 文件。但是,这不适用于 CSS 和图像。

例子,

/App/Projects/Search

易于处理和提供服务,我们无论如何都看不到原始 CSHTML 下载。

App/Views/Projects/Search.cshtml

我在访问方面几乎不需要帮助

/App/Projects/Search.css
/App/Projects/some-button.png

在路径

/App/Views/Projects/Search.css
/App/Views/Projects/some-button.png

由于这些不是 CSHTML,因此取景器找不到它们,而且我需要将它们作为静态下载提供,除了 cshtml、aspx 和注册的 mime 类型之外的任何东西。

此外,我们还为移动设备和平板电脑提供了 DisplayModes,这使得管理资源变得更加困难。

【问题讨论】:

  • 为什么这些资源在 Views 文件夹中? Views 文件夹用于...视图。
  • @AntP 我当然知道,资源是 CSS,视图内部使用的图像。
  • 将它们放在“css”和“images”文件夹中的views文件夹之外。
  • @AntP 请阅读这个问题,我们已经将它们放在目录之外的视图中。

标签: c# asp.net-mvc asp.net-mvc-routing


【解决方案1】:

您可以编辑 ~/Views 文件夹中的 web.config 以允许通过将 *.cshtml 添加到路径参数来访问除 .cshtml 文件之外的任何内容

<system.webServer>
   <handlers>
     <remove name="BlockViewHandler"/>
     <add name="BlockViewHandler" path="*.cshtml" verb="*" preCondition="integratedMode" 
         type="System.Web.HttpNotFoundHandler" />
   </handlers>
</system.webServer>

【讨论】:

    【解决方案2】:

    您不能在 Views 文件夹中放置任何需要提供给浏览器的内容。这包括 CSS(或更少)、图像、javascript 等等......

    这样做的原因是,出于安全原因,MVC 不允许 Web 请求直接访问 Views 文件夹中的任何内容。视图通常包含代码,这些代码可以揭示有关服务器的内部信息。有时人们甚至会做一些愚蠢的事情,比如将用户名和密码放在他们的视图代码中。

    这是为了防止人们只是在浏览器中输入以下内容:

    http://yoursite/Views/Home/index.cshtml
    

    为了下载cshtml文件。

    因此,您根本无法在 Views 文件夹或任何子文件夹中放置您希望浏览器下载的任何内容。

    如果你查看你的 Views 文件夹,你会发现它有它自己的 web.config 文件。在该文件中,您将找到以下部分,其中添加了一个 HttpHandler 来阻止对 Views 文件夹中任何内容的访问。我不建议删除它,因为这会使您的代码易受攻击。

    <system.webServer>
       <handlers>
         <remove name="BlockViewHandler"/>
         <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" 
             type="System.Web.HttpNotFoundHandler" />
       </handlers>
    </system.webServer>
    

    【讨论】:

      【解决方案3】:

      我不知道为什么 UI 依赖项仍然不能保留在 Contents 文件夹中,并且利用 Bundling 功能来打包每个视图的资源。

      【讨论】:

        猜你喜欢
        • 2010-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-16
        • 2015-01-03
        • 2018-05-28
        • 1970-01-01
        相关资源
        最近更新 更多