如何访问ASP.NET Views文件夹中的资源?

时间:2014-06-14 11:01:59

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

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

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

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

    • 应用
      • 控制器
        • 项目
          • Search.cshtml
        • 用户
          • Account.cshtml
  • 内容
    • common.less
    • 应用
      • app.less
      • 一些-button.png
      • projects.less
      • users.less

现在问题发生在我们拥有太多资源并且难以进行交叉引用时,随着我们进行用户界面更改,新视图会随着项目的增长而出现。

我想拥有以下格式的资源,

    • 应用
      • 控制器
        • 项目
          • Search.cshtml
          • search.less
          • 一些-button.png
        • 用户
          • Account.cshtml
          • account.less
          • 一些-button.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,这使得管理资源变得更加困难。

3 个答案:

答案 0 :(得分:1)

您可以在〜/ Views文件夹中编辑web.config,以便通过将 * .cshtml 添加到路径参数

来访问除.cshtml文件之外的任何内容
Sub Macro1()

For i = 1 To ActiveSheet.Range("B" & Rows.Count).End(xlUp).Row Step 1
    If Application.WorksheetFunction.CountIf(ActiveSheet.Range("B1", Range("B" & Rows.Count).End(xlUp)), Range("B" & i).Value) > 1 Then
        MsgBox "Column B Row " & i & " duplicate!"
    End If
Next i

End Sub

答案 1 :(得分:0)

您无法在Views文件夹中放置任何需要提供给浏览器的内容。这包括CSS(或更少),图像,JavaScript,无论......

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

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

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

为了下载cshtml文件。

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

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

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

答案 2 :(得分:0)

我不确定为什么UI依赖关系仍然不能保存在内容文件夹中,并且使用捆绑功能来打包每个视图的资源。