如何在 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 发布工具支持的开发和生产部署之间的对称性。

以下是一些可能的解决方案:

  1. 将子内容部署为父应用程序的子应用程序
  2. 在父部署期间将子内容部署为附加静态文件夹内容
  3. 将子内容部署为父内容的构建依赖项
  4. 使用虚拟目录手动部署子内容

选哪个?这是一个决策树:

  • 子路径是要部署的应用程序/程序集(例如 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>

尽管如此,请注意,以前的 IncludePluginFilesForMsdeployIncludePluginFilesForPackaging,现在在 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(与团队合作时的缺点与上述相同),但要创建一个额外的虚拟目录而不是一个额外的应用程序。