IIS重写,排除文件夹和子文件夹 - Swagger案例

时间:2018-02-20 16:26:20

标签: iis url-rewriting swagger

我有一个Web应用程序,在Azure上使用AspNetCore WebAPI + AngularApp,在我的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/ enter image description here

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

这是我打开http://[MYWEBSITE]/swagger/时可以看到的内容 image

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工作: enter image description here

编辑2:

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

        

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

根据此回复:IIS Handlers exclude a Directory when processing htm requests

我在&#39; D:\ home \ site \ wwwroot \ wwwroot \ swagger&#39;中创建了一个web.config。在Azure上使用以下配置:

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

编辑3:

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

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

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

我会告诉你更新。如果有人有想法,那将会很有帮助。我可能不是唯一试图这样做的人:)。

但问题仍然存在。

2 个答案:

答案 0 :(得分:3)

我终于找到了解决方案!

<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中创建一个Swagger文件夹,而不是直接创建wwwroot /。

这是要在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] /扬鞭

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

答案 1 :(得分:1)

首先,由于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>