Owin Hosted NancyFX 应用 returns 发布到 IIS 后无法加载类型 Nancy.Hosting.Aspnet.NancyHttpRequestHandler

Owin Hosted NancyFX app returns Could not load type Nancy.Hosting.Aspnet.NancyHttpRequestHandler once published to IIS

虽然在 运行 本地通过 VS Studio 包含的 IIS Express 时它工作得很好,但一旦部署到 IIS 8,我的应用程序就会卡住:

System.Web.HttpException: Could not load type 'Nancy.Hosting.Aspnet.NancyHttpRequestHandler'.

后台是MS Owin,用VB(.NET 4.5)写的,注册了3个中间件:OAuth server,JWT bearer Authentication,Nancy。前端是AngularJS。发布的目录中包含正确的 DLL。

IIS 8 已安装并启用 .NET 4.5。 运行集成模式下

我不确定这是否与 web.config 中 Nancy 的配置或 IIS 的配置有关。相关来源如下:

Startup.vb

Public Sub Configuration(app As IAppBuilder)

        Dim issuer As String = "http://obscured-domain"
        Dim audience As String = "obscured-audience-key"
        Dim secret As Byte() = Microsoft.Owin.Security.DataHandler.Encoder.TextEncodings.Base64Url.Decode("obscured-client-secret")

        'CORS Configuration
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)
        app.UseOAuthAuthorizationServer(New OAuthAuthorizationServerOptions() With { _
                                    .AllowInsecureHttp = True, _
                                    .TokenEndpointPath = New PathString("/authenticate"), _
                                    .AccessTokenExpireTimeSpan = TimeSpan.FromHours(1), _
                                    .AccessTokenFormat = New JwtFormat(issuer, audience), _
                                    .Provider = New OAuthServerProvider()
                                })
        app.UseJwtBearerAuthentication(New JwtBearerAuthenticationOptions() With { _
                                       .AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active, _
                                       .AllowedAudiences = New String() {audience}, _
                                       .IssuerSecurityTokenProviders = New IIssuerSecurityTokenProvider() { _
                                           New SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
                                       }
                                   })
        'Content service
        Dim nOpts As New NancyOptions
        nOpts.PassThroughWhenStatusCodesAre(HttpStatusCode.NotFound, HttpStatusCode.InternalServerError)
        app.UseNancy(nOpts)
        'Handle IIS request pipeline staging
        app.UseStageMarker(PipelineStage.MapHandler)
    End Sub

Web.config

    <?xml version="1.0"?>
<configuration>
  <system.web>
    <customErrors mode="Off" />
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <httpHandlers>
      <add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
    </httpHandlers>
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/>
    </handlers>
  </system.webServer>
  <connectionStrings>
    <add name="FTConnStr" connectionString="obscured-connection-string" />
  </connectionStrings>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

南希模块示例

Public Class KnowledgeBaseModule
Inherits NancyModule

    'Get page of article briefs via full-text search
    MyBase.Get("/api/articles/paged/{offset}/{numRows}") = _
    Function(parameters)
            Dim searchFields As FullTextFields = Me.Bind(Of FullTextFields)()
            Try
                Dim results As Dictionary(Of String, List(Of Dictionary(Of String, Object)))
                results = FullTextProvider.pagedSearch(searchFields.fields("SearchString"), CInt(parameters.offset), CInt(parameters.numRows))
                Return Response.AsJson(results)
            Catch ex As Exception
                'temp 500
                Return HttpStatusCode.InternalServerError
            End Try
        End Function

Private Class FullTextFields
    Public Property fields As Dictionary(Of String, String) = New Dictionary(Of String, String) From _
        {
            {"SearchString", String.Empty}
        }
End Class
End Class

由于您使用的是 OWIN,因此您需要使用 SystemWeb host not Nancy's AspNet host。您还需要从 web.config:

中删除这两部分
<httpHandlers>
  <add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
</httpHandlers>

<handlers>
  <add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/>
</handlers>

您的 bin 文件夹中可能有 nancy 主机的副本,这就是它在本地运行但在部署时不起作用的原因。