在 ASP.NET MVC (C#) 上提供静态文件

Posted

技术标签:

【中文标题】在 ASP.NET MVC (C#) 上提供静态文件【英文标题】:Serving static file on ASP.NET MVC (C#) 【发布时间】:2014-05-29 05:43:41 【问题描述】:

我对 .NET 框架完全陌生,我想知道提供静态内容和访问用户生成内容的最佳方式是什么。

假设我有以下文件:

logo.jpg
document.pdf
etc.doc

我应该把这个放在哪里(在哪些文件夹上)?我如何访问它?

最后,将其提升到另一个层次。假设我有一个允许用户上传文档的网络应用程序(比如说一些图片)。我想知道我的文件夹/目录的结构应该如何?

在 django / CI 中,我通常会有一个如下文件夹:

应用程序/all-web-app-related-folder-and-file-goes-here 上传/all-related-user-generated-content-goes-here-categorized-by-file-type 资产/css-javascript-document-would-go-here

注意:我没有做过任何事情,也没有做过任何尝试。仅仅是因为我不知道如何访问尝试静态内容。我曾经尝试访问位于 Content/Scripts 文件夹中的 *.css 或 *.js 文件。

即:localhost:12345/Scripts/jquery.js

事实证明,这在 ASP.NET MVC 中并不是一个简单的过程

哦,顺便说一句, 在某些情况下,我也想从我的 css 文件中访问我的图像。这给我带来了另一个困惑。

编辑 1:我阅读了以下文章

http://www.c-sharpcorner.com/uploadfile/dhananjaycoder/working-with-images-in-Asp-Net-mvc-framework/

但是它不适用于我当前版本的 MVC(我使用的是 MVC 5)

编辑 2:所以,这就是我迄今为止一直在尝试的内容

    我在根目录(与模型、控制器等同级)上创建了一个名为 Assets 的文件夹。 我在 Asset 内部创建子文件夹(即图像、文档等)

    然后我想直接从我的视图中访问这些文件,我会这样:

    img src="@Url.Content("~/Asset/images/picture.png")"

如果我想访问图像文件,上面的例子是合适的。

但我不确定这是否是理想的方法。然而,这是我目前能遇到的最简单的解决方案(或者我应该说,相当幼稚)。

任何提示将不胜感激。

【问题讨论】:

如果你想在Content/Scripts文件夹中访问jquery.js,那么这应该可以:localhost:12345/Content/Scripts/jquery.js 你不会想把它放在一个视图中。一旦您将其移至生产服务器,它就会中断。 严格来说它不是 js 文件,对于 *.css 和 *.js 文件,我更喜欢 BundleConfig,因为它还可以即时压缩我的所有文件(这非常漂亮)。我只想知道访问静态内容(如文档和/或图像)的最佳方式(如果不是常用方式)是什么。 @ekad '@Url.Content' 现在几乎是多余的 通常情况下,ASP.Net MVC 会自动添加一个 Images 文件夹,但是像您在 EDIT 2 中提到的那样创建一个文件夹是没有问题的。您可以创建一个上传文件夹并记住设置允许您使用应用程序添加文件的正确权限。 【参考方案1】:

假设我有以下文件:logo.jpg、document.pdf、etc.doc,我应该把它放在哪里(在哪些文件夹上)?我如何访问它?

您在 EDIT 2 上的内容完全没问题。 MVC 框架足够智能,可以禁用字典浏览。如果您尝试资产 /assets//assets/images,您将获得 403。

此外,即使您有一个名为“assets”的控制器、一个名为“images”的方法和一个字符串 id “picture.png”,请求也不会命中控制器方法。相反,它仍会为您提供图像文件。看起来 MVC 优先于它找到的静态文件而不是 MVC 路由?

假设我有一个允许用户上传文档的网络应用程序(比如说一些图片)。我想知道我的文件夹/目录的结构应该是怎样的?

如果您打算将用户上传的内容作为物理文件存储在应用程序中(而不是将它们保存到持久性存储中),您可以在根目录上创建一个类似“uploads”的文件夹并将他们的上传内容放在那里。

我会通过他们的 ID(希望它是一个 GUID 而不仅仅是整数 ID)将他们的上传文件分隔到“上传”下的不同子文件夹中,以防万一你想在前端显示上传路径时,用户不能轻易猜猜其他用户的上传在哪里:

// assets
// uploads
//     xxxx-xxxx-xxxx-xxxx
//         files
//     xxxx-xxxx-xxxx-xxxx
//         files

不要忘记在您将应用发布到的服务器上设置此上传​​文件夹的权限。

在某些情况下,我还想从我的 css 文件中访问我的图像。

在这种情况下,您将不得不使用相对 URL,并且 MVC 默认其根为 ~/Content。例如,假设您想使用保存在 /assets/images/ 下的图片.png 作为块的背景图片:

#test-block 
    width: 250px;
    height: 250px;
    background-image: url(`~/assets/images/picture.png`);'
    background-size: cover;

您认为它会正确访问图片并将其用作块的背景。但实际上,它会生成如下内容:

background-image: localhost/content/~/assets/images/picture.png

这很糟糕,因为您必须手动返回 1 级才能抓取图像,使用 ../ 而不是 ~/

background-image: url(`../assets/images/picture.png`);'

对我来说,这不是一个公认的解决方案,如果您将应用程序发布到服务器上的虚拟文件夹(不是 wwwroot),那将是非常错误的。

对于设置这样的背景图片,我更喜欢在@Url.Content() 的帮助下使用内联样式,因为我不需要担心它们的路径是如何相互关联的:

<div id="test-block" 
    style="background-image: url('@Url.Content("~/assets/images/picture.png")');">
</div>

【讨论】:

【参考方案2】:

ASP.NET MVC 默认允许静态文件服务。而不是使用@URL.Content 直接写以/开头的路径表示根文件夹

<img src="/Asset/images/picture.png" />

【讨论】:

为了做到这一点,您需要波浪号来表示应用程序的根,而不是站点的根:&lt;img src="~/Asset/images/picture.png" /&gt;

以上是关于在 ASP.NET MVC (C#) 上提供静态文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET MVC3 中通过 HTTPS 提供静态文件(在 ~/Content 中)

ASP.NET MVC 小牛之路]02

ASP.NET MVC 路由:绕过路径的静态文件处理程序

Web APi Vs MVC 和在 ASP.net 核心 Web APi 中提供静态文件

使用 ASP.net、C#、MVC 在模板中生成 pdf

ASP.NET MVC C# 如何分隔导航栏链接?