【问题标题】:Project subdirectory as root for static files项目子目录作为静态文件的根目录
【发布时间】:2014-09-04 15:16:56
【问题描述】:

ASP.NET MVC 新手,我正在使用 Visual Studio 2013 向导创建一个 Web 应用程序。它会创建几个用于提供静态文件的文件夹:ContentScripts 等。

其他语言的框架(例如 TurboGears)有一个仅用于静态内容的显式目录,消除了提供页面源代码而不是处理它的风险,这是 PHP 网站的典型配置错误。

然而,ASP.NET 很乐意在应用程序的根目录中提供任何内容,例如http://localhost:1740/Project_Readme.html 只要它有正确的扩展名。只有Views 文件夹受Web.config 保护。

如何将应用程序配置为使用项目根目录以外的其他目录来存储静态文件。例如。如果将文件favicon.ico 放入子目录Content,它应该可以作为http://localhost:1740/favicon.ico 访问,但在Content 目录之外没有任何内容,除非由控制器返回。

在此目录中不应执行任何操作,也就是说,如果将 *.cshtml 文件放入此目录,则文件的内容(源代码)应以text/plain 的形式传递。

最终应用程序将在 Linux 上使用 mod_mono 运行。

【问题讨论】:

标签: asp.net-mvc routes


【解决方案1】:

更新:

本,

建议的解决方案仅适用于 Owin。要使其在 MVC 应用程序中运行,您必须仅使用 asp.net MVC 6(asp.net core 或 asp.net 5 的一部分)。但是,通过 Web API,您也可以使用旧版本。要设置应用程序,请使用以下步骤:

  1. 使用 Visual Studio 模板创建一个空项目(不要选择 Web API 或 MVC)

  2. 将以下 Nuget 包添加到项目中:

    Microsoft.AspNet.WebApi

    Microsoft.AspNet.WebApi.Owin

    Microsoft.Owin.Host.SystemWeb

    Microsoft.Owin.StaticFiles

  3. 添加 Startup.cs 文件并使用以下内容装饰命名空间

[程序集:OwinStartup(typeof(Startup))]

  1. 将以下代码添加到 Stratup.cs 类中

    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new {id = RouteParameter.Optional}
            );
        //Configure the file/ static file serving middleware
        var physicalFileSystem = new PhysicalFileSystem(@".\client");
        var fileServerOptions = new FileServerOptions
        {
            EnableDefaultFiles = true,
            RequestPath = PathString.Empty,
            FileSystem = physicalFileSystem
        };
    
        fileServerOptions.DefaultFilesOptions.DefaultFileNames = new[] {"index.html"};
        fileServerOptions.StaticFileOptions.ServeUnknownFileTypes = true;
        fileServerOptions.StaticFileOptions.FileSystem = physicalFileSystem;
        app.UseFileServer(fileServerOptions);
        app.UseWebApi(config);
    }
    
    1. 这应该会很神奇。现在您可以在 IIS 中托管应用程序。 IIS 将仅从客户端文件夹提供静态资产。添加服务器文件夹并添加控制器。

Microsoft.Owin.Host.SystemWeb 有助于在 IIS 中托管 Owin 应用程序。文件服务选项帮助 IIS 仅从客户端文件夹提供静态文件。

如果您有任何问题,请告诉我。


根据您的问题,您想要实现的项目结构应如下所示。

基本上,您将只有两个文件夹,客户端和服务器。静态文件仅从客户端文件夹提供。服务器文件夹不可访问。如果这是您需要的,那么可以使用带有静态文件服务中间件的 Owin Self Host 轻松实现。

自主机不依赖于 IIS。但是,如果您计划在 Linux 上托管此应用程序,则可以使用 Asp.NET CORE 1.0。稍后,如果您决定在 Windows 内的 IIS 上托管应用程序,则可以通过添加 Microsot.Owin.Host.SystemWeb nuget 包轻松实现。

关于这个主题有很多很棒的博客文章。这是其中之一的link。这是在 Asp.NET Core 中实现相同功能的 link

希望这能解决您的问题,如果您有任何问题,请告诉我。

谢谢你, 索玛。

【讨论】:

  • 您正确理解了这个问题,但我不明白该怎么做,我在 Windows 上。从你的链接我得到 var config = new HttpConfiguration(); config.Routes.MapHttpRoute(名称:“DefaultApi”,routeTemplate:“api/{controller}/{id}”,默认值:new { id = RouteParameter.Optional }); app.UseWebApi(config); app.UseFileServer(true);我在哪里设置文件路径和服务器路径?我如何告诉 iis 从哪里提供服务?它比代码更有效吗?添加了 Owin 层
  • 您好,感谢您的赏金。如果此解决方案回答了您的问题,请将我的回答标记为已接受。谢谢。
  • 非常感谢您的帮助,我没有开始这个问题,所以我无法接受答案
  • 明白。感谢您的回复,如果您有任何问题,请告诉我。
  • 效果很好!我还必须按照此答案stackoverflow.com/a/36297940/5740181 中的说明对 web.config 进行一些小改动
【解决方案2】:

我找到的最好的解决方案是忽略asp.net正常的方式,写一个新的方式

        public override void Init()
        {
            BeginRequest -= OnBeginRequest;
            BeginRequest += OnBeginRequest;
        }


        protected void OnBeginRequest(object sender, EventArgs e)
        {
            if (Request.Url.AbsolutePath.StartsWith("/endPoint"))
            {
                Context.RemapHandler(endPoint);
            }
            else
            {
                Context.RemapHandler(staticHandler);
            }
        }

让endPoint和staticHandler实现IHttpHandler 它可以工作,但每个静态文件都通过 c# 移动,所以可能有一个性能更好的解决方案

【讨论】:

  • 感谢您对此进行调查。一旦我再次使用 ASP.NET 做一些事情,我会试试这个。
  • 这是一个糟糕的性能解决方案,我希望有人能给我一个更好的解决方案
猜你喜欢
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 2013-01-10
相关资源
最近更新 更多