我们有一个使用ASP.NET Core 1.0 RC1并在IIS上托管的应用程序。它工作正常。现在我们有静态内容,可以在文件共享上使用,并且应该可以从应用程序访问。
在ASP.NET 5之前,我们在IIS中添加了一个虚拟目录,可以轻松访问共享内容。使用我们托管的ASP.NET 5应用程序,遗憾的是这似乎不起作用。我们只是在尝试访问静态内容时得到404
。
我们的应用程序正在使用app.UseIISPlatformHandler()
和app.UseStaticFiles()
,但这不起作用。我们发现我们可以使用app.UseFileServer()
和自定义FileServerOptions
来获得所需的行为,但我们很好奇是否也可以使用在IIS中添加虚拟目录的正常“旧”方式。
答案 0 :(得分:16)
我今天遇到了这个问题,最后设法解决了这个问题。诀窍(对我而言,可能不适合所有人)确保在子应用程序中禁用aspNetCore
处理程序并在主(ASP.NET Core)应用程序中启用。
我的ASP.NET核心应用程序有一个基本的Web.config
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" type="" modules="AspNetCoreModule" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\bin\Debug\netcoreapp2.0\myapp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
并且在IIS中作为子应用程序添加的应用程序已
<configuration>
<!-- removed -->
<system.webServer>
<handlers>
<remove name="aspNetCore" />
</handlers>
</system.webServer>
</configuration>
答案 1 :(得分:11)
我找到了一个我认为必须由OP编写的博客。
结果不是在IIS中使用虚拟目录,而是将Startup.cs中的路径映射到物理服务器目录。我希望OP不介意我已经粘贴了下面的博客,但它帮助了我今天第一次遇到这个问题。
来源:https://www.jauernig-it.de/asp-net-coreiis-serving-content-from-a-file-share/
在某些情况下,当您想要在应用程序中提供静态内容时,这不是其中的一部分,例如:因为它存在于公共文件共享上。由业务部门管理的网站内容可能就是这样一个用例。在Core之前的ASP.NET中,这在IIS中没有问题:只需在IIS网站中创建一个虚拟目录并将其指向文件共享。
不幸的是,使用ASP.NET Core,这种方法不再适用。如果在IIS中向ASP.NET Core应用程序添加虚拟目录,则无法识别该目录并返回404。这是因为DNX / Kestrel在IIS下运行(使用HttpPlatformHandler模块),IIS只会代理请求。 Kestrel不知道IIS中的任何虚拟目录。并且因为ASP.NET Core应用程序独立于IIS而且也可以在没有它的情况下运行(例如运行Kestrel standalone),这应该被视为一件好事。
但是现在我们需要另一个解决方案来解决我们的问题...幸运的是,ASP.NET Core为我们提供了一个程序化界面来从任何地方提供文件。只需将以下代码添加到Startup.cs Configure()方法:
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(@"\\server\path"),
RequestPath = new PathString("/MyPath"),
EnableDirectoryBrowsing = false
});
这实质上是将文件服务器添加到物理服务器路径,然后在某个请求路径上可用,在这种情况下禁用目录浏览。您还可以使用新的PhysicalFileProvider(env.WebRootPath +&#34; \ path&#34;)从相对于您的应用程序的路径提供服务(给定env的类型为IHostingEnvironment作为Configure()的参数)。瞧,就是这样。没有必要在IIS中添加“虚拟目录”,这个东西已被弃用并且已成为过去。对我来说,这是一件好事,因为我们更加独立于整个IIS ......
答案 2 :(得分:4)
不直接。
你知道,问题是,当你有一个.NET-Core应用程序时,应用程序是在Kestrell中运行的,而不是在IIS中运行的。
现在,要在IIS中托管您的.NET-Core应用程序,AspNetCoreModule在端口X上使用Kestrell启动您的.NET-Core应用程序127.0.0.1,然后从您的iis-domain +虚拟目录反向代理流量到127.0.0.1上的端口X(它可能使用除TCP之外的其他东西)。
问题1是,Kestrell功能非常有限,意味着没有虚拟目录。
问题2是,与nginx不同,IIS不能正确地进行反向代理,或者我们应该说“完全”。
IIS可以转发domainxy:80到127.0.0.1:随机正常。 但它做得不好的是重写domainxy:80 / foo到127.0.0.1:random(images,header,json-ajax-results,urls,return-urls,cookies等,反之亦然)。 相反,它重写域:80 / foo到127.0.0.1:random/foo,如果127.0.0.1:random(Kestrell)上的服务器不支持虚拟目录,这是一个问题。
因此,如果您想在虚拟目录中运行您的应用程序,您有两个选择(都涉及修改“您的”应用程序 - 如果您可以这样做):
1)如果您的应用程序仅部署一次,请将所有内容放入目录“foo”(包括MVC控制器路由)。
2)正如https://github.com/aspnet/Hosting/issues/416#issuecomment-149046552中所建议的,您可以让应用程序框架为您模拟该文件夹,类似于RoR:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
string virtual_directory = "/Virt_DIR";
// virtual_directory = "/";
if (virtual_directory.EndsWith("/"))
virtual_directory = virtual_directory.Substring(0, virtual_directory.Length - 1);
if (string.IsNullOrWhiteSpace(virtual_directory))
Configure1(app, env, loggerFactory); // Don't map if you don't have to
// (wonder what the framework does or does not do for that case)
else
app.Map(virtual_directory, delegate(IApplicationBuilder mappedApp)
{
Configure1(mappedApp, env, loggerFactory);
}
);
}
// Configure is called after ConfigureServices is called.
public void Configure1(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
[...] (here comes what used to be in your old Configure method)
您必须在某处配置虚拟目录的名称。 当您在JavaScript / ajax-requests中拥有/返回URL时,请小心,它们不会自动映射。你必须自己做这件事,但过去也是如此。
真的,就像RoR:
映射Rails.application.config.relative_url_root || “/”做 运行RedmineApp :: Application
端
对于应用程序中的虚拟目录:
不,这不是那么简单。
IIS是一个完整的Web服务器,它将像那里一样提供该映射目录的内容(如果它可以读取内容)。
如果您将整个父目录转发到Kestrell,那么IIS无法提供子目录,您应用程序必须这样做。这意味着您必须为该特定目录设置静态文件服务器,并告诉它文件的位置,就像您所做的那样。
您可以做的是告诉IIS不要代理该特定的虚拟子目录(就像您可以在nginx中定义静态文件位置一样 - 除了IIS可能不支持该功能)。
但是,如果Windows具有该功能(mklink),则可以在应用程序目录中创建一个符合网络文件夹的符号链接。然后.NET Core应该能够静态地提供它。但实际上,这听起来像是一个黑客。
如果无法配置IIS,则应该使用app.UseFileServer()并在数据库中定义文档的位置。这样您就可以稍后删除并重新插入应用程序。
答案 3 :(得分:1)
我知道这个问题是1,8年,但如果有人需要解决同样的问题,请尝试使用:
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); // For the wwwroot folder
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "images")),
RequestPath = new PathString("/MyImages")
});
}
完全可以将PhysicalFileProvider的参数更改为任何本地或共享文件夹,并使用此文件提供文件。
以这种方式执行此操作并非建议使用安全性。但是,对于研究提出,它是可以接受的。
静态文件模块提供no 授权检查。它提供的任何文件,包括那些文件 wwwroot是公开的。基于的服务文件 授权:将它们存储在wwwroot和任何目录之外 可以访问静态文件中间件并通过它服务它们 控制器动作,返回授权所在的FileResult 应用
在Microsoft的Asp.Net文档中,我们可以找到更完整的信息来帮助解决此问题。
点击此链接:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files
答案 4 :(得分:0)
我的解决方案是在path="/"
文件上使用path="*"
代替web.config