【问题标题】:IIS Rewrite, Exclude Folders and Subfolders - Swagger CaseIIS 重写、排除文件夹和子文件夹 - Swagger 案例
【发布时间】:2018-07-31 02:01:09
【问题描述】:

我在 Azure 上有一个带有 AspNetCore WebAPI + AngularApp 的 WebApp,在我的 Web.Config 中有 IIS 重写规则,基于这篇文章:https://weblog.west-wind.com/posts/2017/Apr/27/IIS-and-ASPNET-Core-Rewrite-Rules-for-AspNetCoreModule

我想避免在 Swagger 上重写,所以我将这条规则添加为第一条规则:

<rule name="swagger" enabled="true" stopProcessing="true">
  <match url="swagger/.*" />
  <action type="None" />
</rule>

基于本网站:https://www.regextester.com/

规则应该排除 swagger/ 以及所有子文件夹和文件。但事实并非如此。

这是我打开http://[MYWEBSITE]/swagger/时看到的

Angular 应用程序正常工作。

我已经对此进行了一些搜索:

感谢您的帮助。


编辑 1:

只是为了让您知道,使用默认的 web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>

    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\[MYWEBAPP].Api.dll" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" />
  </system.webServer>
</configuration>

我可以正确地看到 Swagger 工作:


编辑 2:

在我的测试过程中,我删除了重写规则,只关注处理程序,我注意到这些规则有问题:

这很正常,Swagger 是在 .NetCore WebApi 中构建的。我正在寻找一种从处理程序中排除特定文件夹的方法。

基于此回复:IIS Handlers exclude a Directory when processing htm requests

我在 Azure 上的“D:\home\site\wwwroot\wwwroot\swagger”中创建了一个 web.config,配置如下:

<system.webServer>
     <handlers>
       <remove name="StaticFileModuleHtml" />
       <remove name="StaticFileModuleJs" />
       <remove name="StaticFileModuleCss" />
       <remove name="StaticFileModulePng" />
     </handlers>
</system.webServer>

编辑 3:

显然问题来自静态处理程序。 如果我想使用 Swagger,我需要禁用它们。 如果我想访问我的 Angular 应用程序,我需要添加它们。

我在这里看到了:https://github.com/domaindrivendev/Swashbuckle.AspNetCore#swashbuckleaspnetcorecli

似乎可以直接从 SwaggerUi 中提取内容到构建的文件夹中,但目前,Nugget 包不可用: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/601

我会及时通知你。如果有人有想法,那将很有帮助。我可能不是唯一尝试这样做的人:)。

但问题仍然存在。

【问题讨论】:

    标签: iis url-rewriting swagger


    【解决方案1】:

    我终于找到了解决办法!

    <configuration>
      <system.webServer>
        <rewrite>
          <rules>
            <rule name="wwwroot-static" stopProcessing="true">
              <match url="([\S]+[.](html|htm|svg|js|css|png|gif|jpg|jpeg))" />
              <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_URI}" pattern="swagger/" negate="true" />
              </conditions>
              <action type="Rewrite" url="wwwroot/{R:1}" />
            </rule>
            <rule name="empty-root-index" stopProcessing="true">
              <match url="^$" />
              <action type="Rewrite" url="wwwroot/index.html" />
            </rule>
            <rule name="AngularJS-Html5-Routes" stopProcessing="true">
              <match url=".*" />
              <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                <add input="{REQUEST_URI}" pattern="api/" negate="true" />
                <add input="{REQUEST_URI}" pattern="swagger/" negate="true" />
              </conditions>
              <action type="Rewrite" url="wwwroot/index.html" />
            </rule>
          </rules>
        </rewrite>
        <handlers>
          <add name="StaticFileModuleHtml" path="*.htm*" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
          <add name="StaticFileModuleSvg" path="*.svg" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
          <add name="StaticFileModuleJs" path="*.js" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
          <add name="StaticFileModuleCss" path="*.css" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
          <add name="StaticFileModuleJpeg" path="*.jpeg" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
          <add name="StaticFileModuleJpg" path="*.jpg" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
          <add name="StaticFileModulePng" path="*.png" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
          <add name="StaticFileModuleGif" path="*.gif" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
          <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
        </handlers>
        <aspNetCore processPath="dotnet" arguments=".\[MYWEBAPP].dll" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" />
      </system.webServer>
    </configuration>
    

    我在编辑 2 中的错误是在 wwwroot/wwwroot 中而不是直接在 wwwroot/ 中创建 Swagger 文件夹。

    这是要添加到 wwwroot/swagger 的 web.config:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.webServer>
        <handlers>
          <!--We need to add this web.config to avoid conflict on Azure between Angular App and Swagger -->
          <remove name="StaticFileModuleHtml" />
          <remove name="StaticFileModuleSvg" />
          <remove name="StaticFileModuleJs" />
          <remove name="StaticFileModuleCss" />
          <remove name="StaticFileModuleJpeg" />
          <remove name="StaticFileModuleJpg" />
          <remove name="StaticFileModulePng" />
          <remove name="StaticFileModuleGif" />
        </handlers>
      </system.webServer>
    </configuration>
    

    您现在可以访问:

    • http(s)://[MYWEBAPP]
    • http(s)://[MYWEBAPP]/[ANGULAR ROUTE]
    • http(s)://[MYWEBAPP]/Swagger

    我希望它会帮助某人:)。如果您有任何问题,请提出。

    【讨论】:

    • 这似乎确实有效,谢谢!除了 web.config 文件,它需要放在 web 应用程序的根目录中。所以代替 - /wwwwroot/swagger/web.config 我把它移到: - /swagger/web.config
    • 嗨,很高兴我的解决方案对你有用 :) 也许我的回答不够清楚,我想说的是,如果你把 web.config for swagger 放在 'D:\home\site\ wwwroot\swagger',它的工作原理。我一开始的错误是把它放在'D:\ home \ site \ wwwroot \ wwwroot \ swagger'中,这不起作用。我理解你的回答了吗?
    • 您不应将服务器配置文件放入 wwwroot 文件夹,因为它将作为静态内容提供。因此,我将配置文件放入 wwwroot 外部的 swagger 文件夹中,然后它就可以工作了! :)
    • 我很难知道你在说哪个 wwwroot,因为有 2 个 wwwroot,'wwwroot' 和 'wwwroot/wwwroot'。在我这边,如果我将 swagger 的 web.config 放在“D:\home\site\wwwroot\swagger”中,它就可以工作。我的解决方案是针对 Azure 的,你可能可以适应其他平台。也许您没有使用 Azure,并且您的配置与我的不同。最重要的是它适合你:)。
    • 您最好在根 web.config 中使用 &lt;location path="swagger"&gt;...&lt;/location&gt;。并在那里进行所有的拆除工作。这更加清晰,并且该位置不必实际存在。
    【解决方案2】:

    首先,因为 Swagger 不会创建一个真正的文件夹,所以在 wwwroot 中创建一个名为 swagger 的文件夹并将 web.config 放入其中并不是一个完美的主意。我认为您的 swagger UI 的默认地址是:localhost:[random-port-number]/swagger/index.html。根据您的招摇版本,它可能会有所不同,您也可以将其更改为如下所示的其他内容:

    app.UseSwagger(c =>
    {
        c.RouteTemplate = "SampleApi/swagger/{documentName}/swagger.json";
    });
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/SampleApi/swagger/v1/swagger.json", "Sample API");
        c.RoutePrefix = "SampleApi/swagger";
    });
    

    有关详细信息,请参阅this article。我的 Swashbuckle.AspNetCore 的版本是 4.0.1 我还在路由中添加了 API,以便能够通过 React 或 Angular 或其他任何方式从字体端在您的项目中使用您的 Microsoft Web API, 您只需将其添加到项目中的主 web.config 中即可:

    <rules>
        <rule name="wwwroot-static" stopProcessing="true">
          <match url="([\S]+[.](html|htm|svg|js|css|png|gif|jpg|jpeg|ico|axd))" />
           <!--Handle static file requests and server them from the wwwroot--> 
          <conditions logicalGrouping="MatchAll">
            <add input="{HTTP_METHOD}" pattern="GET|HEAD" />
            <add input="{REQUEST_URI}" pattern="/swagger/.*" negate="true" />
          </conditions>
          <action type="Rewrite" url="wwwroot/{R:1}" />
        </rule>
    
        <rule name="html5-routes" stopProcessing="true">
          <match url=".*" />
          <!-- Handle all paths except /api/ and pass the route onto the wwwroot/index.html -->
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <!-- Add rule to negate file requests e.g. css/html/images-->
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <!-- Add rule to negate directories-->
            <add input="{REQUEST_URI}" pattern="^/api/" negate="true" />
            <add input="{REQUEST_URI}" pattern="/swagger/.*" negate="true" />
            <!-- Add rule to negate paths and let them through the MVC-->
            <add input="{HTTP_METHOD}" pattern="GET|HEAD" />
          </conditions>
          <action type="Rewrite" url="wwwroot/index.html" />
        </rule>
    </rules>
    

    【讨论】:

    • 感谢阿拉什的帮助:)。
    猜你喜欢
    • 2013-11-08
    • 2013-05-02
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多