如何在 iisexpress vs2015 中设置具有相同端口和域但路径不同的多个应用程序
how to setup multiple apps with same port and domain but different paths in iisexpress vs2015
我目前正在将一个大的 asp.net 核心解决方案拆分为多个较小的解决方案,每个解决方案都有一个应用程序。
为此,基本应用需要指向
www.originalApp.com
我的每个小应用程序都将使用路径
访问
www.originalApp.com/SplittedApp
我已经通过 applicationHost.config
中的以下设置使用 IIS 成功获得此 运行
<site name="OriginalApp" id="3" serverAutoStart="true">
<application path="/" applicationPool="OriginalAppPool">
<virtualDirectory path="/" physicalPath="OriginalAppPath/>
</application>
<application path="/SplittedApp" applicationPool="splittedApp">
<virtualDirectory path="/" physicalPath="splittedAppPath />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:82:" />
<binding protocol="http" bindingInformation="IpAddress:originalApp" />
</bindings>
<applicationDefaults applicationPool="Fire.Frontend" />
</site>
我已经在 IISExpress 的 applicationHost.config 文件中为这两个应用程序尝试了此设置的多种变体,但出现了不同的问题。
我的应用程序 launchSettings.json 在拆分后的应用程序中看起来像这样
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:9345/splitted app",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
和原始应用程序
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:9345",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
当前设置无法加载第二个应用程序,因为正在使用同一个端口,但是我需要使用同一个端口,这样我就可以附加路径并有效地导航两个应用程序之间的页面。
我很难相信使用 IIS Express 无法实现我试图实现的目标,因为它可以与 IIS 一起正常工作。
我在 SO 和网上的博客上阅读了很多 post,但我找不到任何有相同问题的人,而且 none 似乎对我有用的问题的解决方案,所以如果有人能指出我正确的方向,将不胜感激。
谢谢。
PS
我不确定我在问题中添加的标签是否正确,所以如果有更好的标签要添加,请告诉我。
不确定是否可行,因为每个 IIS Express Web 应用程序都应该针对每个应用程序和每个协议使用不同的端口。
我遇到了类似的问题,最终在本地随机端口下安装了 .net 核心应用程序 运行,并在 DEV 服务器上设置了正确的域和虚拟目录。
在我们的构建过程中,我们选择继续 "Package/Publish" 到安装了 .NET Core 处理程序的 IIS 服务器。因此,我们的选择有些限制,因为必须有一些方法来提供 Web 发布工具支持的开发和生产部署之间的对称性。
以下是一些可能的解决方案:
- 将子内容部署为父应用程序的子应用程序
- 在父部署期间将子内容部署为附加静态文件夹内容
- 将子内容部署为父内容的构建依赖项
- 使用虚拟目录手动部署子内容
选哪个?这是一个决策树:
- 子路径是要部署的应用程序/程序集(例如 WebAPI)吗?如果是,请选择选项 1。
- 子路径是一个松散耦合的包,单独版本控制还是由另一个团队构建?如果是,请选择选项 3。
- 在 backup/restore、部署和安全操作期间,路径是否在服务器的单个单元中得到最好的维护?如果是这样,请选择选项 4。
- 否则,选择选项 2。
让我们快速浏览一下这些:
1。将子内容部署为父应用程序的子应用程序
这在 IIS 部署目标(例如 public 网络服务器)上很容易。使用相同的旧工具或手动在发布目标服务器上创建子应用程序。然而,这在开发工作站上更难。在下图中,顶部显示了 .NET Core 应用程序的配置方式,而底部显示了 .NET Framework 应用程序在 Visual Studio UI 中的呈现方式:
在这两种情况下,它都会在 .vs\config\applicationhost.config
文件中创建它们;但新的 ASP.NET 核心工具仅在该工作站 .config
文件中创建根应用程序(不是子应用程序)。我们可以为每个开发人员手动编辑它,但不幸的是我们通常不想签入这些文件,因为它们有本地机器路径。无论如何,如果您尝试使用旧的多项目启动 属性 方法,您最终会看到多个站点尝试在同一端口 运行 失败。相反,您想要的是一个具有多个应用程序的站点。这是这样一个(手动编辑的)工作配置的示例:
<site name="MyNamespace.RootWeb" id="5">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="E:\Development\MySolution\MyProject" />
</application>
<application path="/assets" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="E:\Development\MySolution\MyProject.Assets" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:55519:localhost" />
</bindings>
</site>
另一种方法可能是创建一个 .target
文件以添加 Visual Studio 已为 ASP.NET 核心项目丢失的功能,通过扫描您的项目 launchsettings.json
文件,并将所有项目 URL 前缀合并到单个中间 XML <sites />
片段文件中,当任何片段比片段更新时,并将片段合并到 applicationhost.config
(甚至执行更改冲突通过中间文件)。如果我这样做,我会通知你。
最后,您可以更改项目 Web 启动应用程序。不是 "project",因为 Kestrel 也不能在同一端口上托管多个应用程序。但是,WebListener 可以,可以接受完成此操作所需的所有命令行参数。
2。在父部署期间将子内容部署为附加静态文件夹内容。
如果我们实际上没有正在构建的相关程序集,我们可以 运行 在单个应用程序中。在开发工作站上,我们可以使用 if (env.IsDevelopment()) IApplicationBuilder.UseStaticFiles();
有条件地重定向子内容的路径。我们仍然需要在服务器上获取内容 运行ning。为此,我们将使用 IncludePluginFilesForMsdeploy
部署指令,类似于:
<PropertyGroup>
<PipelineCopyAllFilesToOneFolderForMsdeployDependsOn>
IncludePluginFilesForMsdeploy;
$(PipelineCopyAllFilesToOneFolderForMsdeployDependsOn);
</PipelineCopyAllFilesToOneFolderForMsdeployDependsOn>
</PropertyGroup>
<Target Name="IncludePluginFilesForMsdeploy">
<ItemGroup>
<FileWrites Include="$(MSBuildProjectDirectory)\bin\**\*" />
<_CustomFiles Include="$(MSBuildProjectDirectory)\bin\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
尽管如此,请注意,以前的 IncludePluginFilesForMsdeploy
是 IncludePluginFilesForPackaging
,现在在 VS 2017 中使用 DotnetPublishFiles
实现了相同的目标,如下所示:
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CustomCollectFiles" BeforeTargets="BeforePublish">
<Message Text="Custom Collect Before Publish" Importance="high" />
<ItemGroup>
<_CustomFiles Include="$(MSBuildProjectDirectory)/../MyProject/compiled/**/*" />
<DotnetPublishFiles Include="@(_CustomFiles)">
<DestinationRelativePath>wwwroot/MyProject/compiled/%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</DotnetPublishFiles>
</ItemGroup>
</Target>
</Project>
3。将子内容部署为父内容的构建依赖项。
同样,对于静态内容(例如浏览器应用程序),我们可能会考虑将该应用程序构建到一个包中,并在开发中要求它进入我们的根应用程序,使用 NuGet、NPM 或类似工具。现在只有一个应用程序要部署这一事实在这里既有利也有弊。对于由不同团队维护的非常松散耦合的包,或者必须为依赖项单独维护版本控制的地方,我会留下这个。
4。使用虚拟目录手动部署子内容。
在服务器上,如果我们不需要子应用程序,我们可能仍希望为该子内容提供一个外部文件夹层次结构。我们可以使用虚拟目录在父目录下反映此内容,并包含部署标志 <DeployAsIisApp>False</DeployAsIisApp>
。或者,我们可以使用 NPM、FTP 或其他一些技术直接部署到服务器。在开发站上,我们可以按照上面的UseStaticFiles()
思路进行。或者,我们可以再次破解 .vs\config\applicationhost.config
(与团队合作时的缺点与上述相同),但要创建一个额外的虚拟目录而不是一个额外的应用程序。
我目前正在将一个大的 asp.net 核心解决方案拆分为多个较小的解决方案,每个解决方案都有一个应用程序。 为此,基本应用需要指向
www.originalApp.com
我的每个小应用程序都将使用路径
访问www.originalApp.com/SplittedApp
我已经通过 applicationHost.config
中的以下设置使用 IIS 成功获得此 运行 <site name="OriginalApp" id="3" serverAutoStart="true">
<application path="/" applicationPool="OriginalAppPool">
<virtualDirectory path="/" physicalPath="OriginalAppPath/>
</application>
<application path="/SplittedApp" applicationPool="splittedApp">
<virtualDirectory path="/" physicalPath="splittedAppPath />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:82:" />
<binding protocol="http" bindingInformation="IpAddress:originalApp" />
</bindings>
<applicationDefaults applicationPool="Fire.Frontend" />
</site>
我已经在 IISExpress 的 applicationHost.config 文件中为这两个应用程序尝试了此设置的多种变体,但出现了不同的问题。
我的应用程序 launchSettings.json 在拆分后的应用程序中看起来像这样
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:9345/splitted app",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
和原始应用程序
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:9345",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
当前设置无法加载第二个应用程序,因为正在使用同一个端口,但是我需要使用同一个端口,这样我就可以附加路径并有效地导航两个应用程序之间的页面。
我很难相信使用 IIS Express 无法实现我试图实现的目标,因为它可以与 IIS 一起正常工作。
我在 SO 和网上的博客上阅读了很多 post,但我找不到任何有相同问题的人,而且 none 似乎对我有用的问题的解决方案,所以如果有人能指出我正确的方向,将不胜感激。
谢谢。
PS 我不确定我在问题中添加的标签是否正确,所以如果有更好的标签要添加,请告诉我。
不确定是否可行,因为每个 IIS Express Web 应用程序都应该针对每个应用程序和每个协议使用不同的端口。
我遇到了类似的问题,最终在本地随机端口下安装了 .net 核心应用程序 运行,并在 DEV 服务器上设置了正确的域和虚拟目录。
在我们的构建过程中,我们选择继续 "Package/Publish" 到安装了 .NET Core 处理程序的 IIS 服务器。因此,我们的选择有些限制,因为必须有一些方法来提供 Web 发布工具支持的开发和生产部署之间的对称性。
以下是一些可能的解决方案:
- 将子内容部署为父应用程序的子应用程序
- 在父部署期间将子内容部署为附加静态文件夹内容
- 将子内容部署为父内容的构建依赖项
- 使用虚拟目录手动部署子内容
选哪个?这是一个决策树:
- 子路径是要部署的应用程序/程序集(例如 WebAPI)吗?如果是,请选择选项 1。
- 子路径是一个松散耦合的包,单独版本控制还是由另一个团队构建?如果是,请选择选项 3。
- 在 backup/restore、部署和安全操作期间,路径是否在服务器的单个单元中得到最好的维护?如果是这样,请选择选项 4。
- 否则,选择选项 2。
让我们快速浏览一下这些:
1。将子内容部署为父应用程序的子应用程序
这在 IIS 部署目标(例如 public 网络服务器)上很容易。使用相同的旧工具或手动在发布目标服务器上创建子应用程序。然而,这在开发工作站上更难。在下图中,顶部显示了 .NET Core 应用程序的配置方式,而底部显示了 .NET Framework 应用程序在 Visual Studio UI 中的呈现方式:
在这两种情况下,它都会在 .vs\config\applicationhost.config
文件中创建它们;但新的 ASP.NET 核心工具仅在该工作站 .config
文件中创建根应用程序(不是子应用程序)。我们可以为每个开发人员手动编辑它,但不幸的是我们通常不想签入这些文件,因为它们有本地机器路径。无论如何,如果您尝试使用旧的多项目启动 属性 方法,您最终会看到多个站点尝试在同一端口 运行 失败。相反,您想要的是一个具有多个应用程序的站点。这是这样一个(手动编辑的)工作配置的示例:
<site name="MyNamespace.RootWeb" id="5">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="E:\Development\MySolution\MyProject" />
</application>
<application path="/assets" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="E:\Development\MySolution\MyProject.Assets" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:55519:localhost" />
</bindings>
</site>
另一种方法可能是创建一个 .target
文件以添加 Visual Studio 已为 ASP.NET 核心项目丢失的功能,通过扫描您的项目 launchsettings.json
文件,并将所有项目 URL 前缀合并到单个中间 XML <sites />
片段文件中,当任何片段比片段更新时,并将片段合并到 applicationhost.config
(甚至执行更改冲突通过中间文件)。如果我这样做,我会通知你。
最后,您可以更改项目 Web 启动应用程序。不是 "project",因为 Kestrel 也不能在同一端口上托管多个应用程序。但是,WebListener 可以,可以接受完成此操作所需的所有命令行参数。
2。在父部署期间将子内容部署为附加静态文件夹内容。
如果我们实际上没有正在构建的相关程序集,我们可以 运行 在单个应用程序中。在开发工作站上,我们可以使用 if (env.IsDevelopment()) IApplicationBuilder.UseStaticFiles();
有条件地重定向子内容的路径。我们仍然需要在服务器上获取内容 运行ning。为此,我们将使用 IncludePluginFilesForMsdeploy
部署指令,类似于:
<PropertyGroup>
<PipelineCopyAllFilesToOneFolderForMsdeployDependsOn>
IncludePluginFilesForMsdeploy;
$(PipelineCopyAllFilesToOneFolderForMsdeployDependsOn);
</PipelineCopyAllFilesToOneFolderForMsdeployDependsOn>
</PropertyGroup>
<Target Name="IncludePluginFilesForMsdeploy">
<ItemGroup>
<FileWrites Include="$(MSBuildProjectDirectory)\bin\**\*" />
<_CustomFiles Include="$(MSBuildProjectDirectory)\bin\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
尽管如此,请注意,以前的 IncludePluginFilesForMsdeploy
是 IncludePluginFilesForPackaging
,现在在 VS 2017 中使用 DotnetPublishFiles
实现了相同的目标,如下所示:
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CustomCollectFiles" BeforeTargets="BeforePublish">
<Message Text="Custom Collect Before Publish" Importance="high" />
<ItemGroup>
<_CustomFiles Include="$(MSBuildProjectDirectory)/../MyProject/compiled/**/*" />
<DotnetPublishFiles Include="@(_CustomFiles)">
<DestinationRelativePath>wwwroot/MyProject/compiled/%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</DotnetPublishFiles>
</ItemGroup>
</Target>
</Project>
3。将子内容部署为父内容的构建依赖项。
同样,对于静态内容(例如浏览器应用程序),我们可能会考虑将该应用程序构建到一个包中,并在开发中要求它进入我们的根应用程序,使用 NuGet、NPM 或类似工具。现在只有一个应用程序要部署这一事实在这里既有利也有弊。对于由不同团队维护的非常松散耦合的包,或者必须为依赖项单独维护版本控制的地方,我会留下这个。
4。使用虚拟目录手动部署子内容。
在服务器上,如果我们不需要子应用程序,我们可能仍希望为该子内容提供一个外部文件夹层次结构。我们可以使用虚拟目录在父目录下反映此内容,并包含部署标志 <DeployAsIisApp>False</DeployAsIisApp>
。或者,我们可以使用 NPM、FTP 或其他一些技术直接部署到服务器。在开发站上,我们可以按照上面的UseStaticFiles()
思路进行。或者,我们可以再次破解 .vs\config\applicationhost.config
(与团队合作时的缺点与上述相同),但要创建一个额外的虚拟目录而不是一个额外的应用程序。