【问题标题】:"Handler for Request not found" error after attempting to implement custom ServiceStackHttpHandlerFactory尝试实现自定义 ServiceStackHttpHandlerFactory 后出现“未找到请求处理程序”错误
【发布时间】:2013-08-26 09:56:17
【问题描述】:

编辑:

该错误似乎与在 web.config 中使用 location 有关。

我能够在一个全新的项目中使用该解决方法,但是,一旦我为 API 指定了特定位置,我又开始看到错误。


我有一个现有的 ASP.NET Web 应用程序,我正在向其中添加服务堆栈。该应用程序严重依赖 ASP.NET 会话。不幸的是,我无法访问我的服务堆栈类中的会话,因为 HttpContext.Current.Session 始终为空。

所以我已经从this Stack Overflow answer 实现了一个 VB.NET 版本的解决方法,但是当我导航到配置了 URL 服务堆栈时,我收到以下错误:

Handler for Request not found: 

Request.ApplicationPath: /
Request.CurrentExecutionFilePath: /api/
Request.FilePath: /api/
Request.HttpMethod: GET
Request.MapPath('~'): D:\Hg\MyApp.Web\
Request.Path: /api/
Request.PathInfo: 
Request.ResolvedPathInfo: /api
Request.PhysicalPath: D:\Hg\MyApp.Web\api\
Request.PhysicalApplicationPath: D:\Hg\MyApp.Web\
Request.QueryString: 
Request.RawUrl: /api/
Request.Url.AbsoluteUri: http://localhost:28858/api/
Request.Url.AbsolutePath: /api/
Request.Url.Fragment: 
Request.Url.Host: localhost
Request.Url.LocalPath: /api/
Request.Url.Port: 28858
Request.Url.Query: 
Request.Url.Scheme: http
Request.Url.Segments: System.String[]
App.IsIntegratedPipeline: True
App.WebHostPhysicalPath: D:\Hg\MyApp.Web
App.WebHostRootFileNames: [aspnetemail.xml.lic,componentart.uiframework.lic,debug.aspx,debug.aspx.designer.vb,debug.aspx.vb,default.aspx,default.aspx.designer.vb,default.aspx.vb,favicon.ico,global.asax,global.asax.vb,licenses.licx,login.aspx,login.aspx.designer.vb,login.aspx.vb,logout.aspx,logout.aspx.designer.vb,logout.aspx.vb,packages.config,MyApp.web.vbproj,MyApp.web.vbproj.user,readme.txt,robots.txt,switch.aspx,switch.aspx.designer.vb,switch.aspx.vb,web.config,web.debug.config,web.release.config,_app_offline.htm,api,apps,app_code,app_data,app_start,bin,content,error,frameset,homepages,my project,obj,_clientdata,_system]
App.DefaultHandler: DefaultHttpHandler
App.DebugLastHandlerArgs: GET|/api/|D:\Hg\MyApp.Web\api\

当我使用默认的服务堆栈 HTTP 处理程序时,一切正常(会话除外)。当我换入SessionHttpHandlerFactory 时,出现上述错误。

根据变通方法的说明,您必须将 type 属性从 ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack 更改为 SomeNamespace.SessionHttpHandlerFactory

Web.Config

<location path="api">
        <system.web>
            <authorization>
                <allow users="*" />
            </authorization>
            <httpHandlers>
                <add path="*" type="MyApp.Web.SessionHttpHandlerFactory" verb="*" />
                <!--<add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" />-->
            </httpHandlers>
        </system.web>

        <!-- Required for IIS7 -->
        <system.webServer>
            <modules runAllManagedModulesForAllRequests="true"/>
            <validation validateIntegratedModeConfiguration="false" />
            <handlers>
                <add path="*" name="ServiceStack.Factory" type="MyApp.Web.SessionHttpHandlerFactory" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
                <!--<add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />-->
            </handlers>
        </system.webServer>
    </location>

这是解决方法使用的两个类,从 C# 转换为 VB.NET:

SessionHandlerDecorator.vb:

Public Class SessionHandlerDecorator
    Implements IHttpHandler
    Implements IRequiresSessionState

    Private Property Handler() As IHttpHandler
        Get
            Return m_Handler
        End Get
        Set(value As IHttpHandler)
            m_Handler = value
        End Set
    End Property
    Private m_Handler As IHttpHandler

    Friend Sub New(handler As IHttpHandler)
        Me.Handler = handler
    End Sub

    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return Handler.IsReusable
        End Get
    End Property

    Public Sub ProcessRequest(context As HttpContext) Implements IHttpHandler.ProcessRequest
        Handler.ProcessRequest(context)
    End Sub
End Class

SessionHttpHandlerFactory:

Imports ServiceStack.WebHost.Endpoints

Public Class SessionHttpHandlerFactory
    Implements IHttpHandlerFactory

    Private Shared ReadOnly factory As New ServiceStackHttpHandlerFactory()

    Public Function GetHandler(context As HttpContext, requestType As String, url As String, pathTranslated As String) As IHttpHandler Implements IHttpHandlerFactory.GetHandler
        Dim handler = factory.GetHandler(context, requestType, url, pathTranslated)
        Return If(handler Is Nothing, Nothing, New SessionHandlerDecorator(handler))
    End Function

    Public Sub ReleaseHandler(handler As IHttpHandler) Implements IHttpHandlerFactory.ReleaseHandler
        factory.ReleaseHandler(handler)
    End Sub

End Class

这是我的服务堆栈实现。就像我说的,它使用默认的服务堆栈 HTTP 处理程序可以完美运行。

AppHost.vb:

Imports ServiceStack.WebHost.Endpoints

<Assembly: WebActivator.PreApplicationStartMethod(GetType(LoginAppHost), "Start")> 

Public Class LoginAppHost
    Inherits AppHostBase

    Public Sub New()
        'Tell ServiceStack the name and where to find your web services
        MyBase.New("My Happy Login API", GetType(LoginService).Assembly)
    End Sub

    Public Overrides Sub Configure(container As Funq.Container)
        'Set JSON web services to return idiomatic JSON camelCase properties
        ServiceStack.Text.JsConfig.EmitCamelCaseNames = True

    End Sub

    Public Shared Sub Start()
        Dim app As New LoginAppHost
        app.Init()
    End Sub
End Class

Login.vb:

Imports ServiceStack.ServiceInterface
Imports ServiceStack.ServiceHost

Public Class LoginService
    Inherits Service

    Public Function Any(request As SSOLogin) As Object

        Return New SSOLoginResponse With {.Valid = True, .RedirectUri = "http://localhost:28858/Iloveturtles.aspx"}

    End Function

End Class

<Route("/login")> _
Public Class SSOLogin
    Public Property UserName As String
    Public Property Key As String
    Public Property Redirect As String
End Class

Public Class SSOLoginResponse
    Public Property Valid As Boolean
    Public Property RedirectUri As String
End Class

我完全不知道如何进行。有什么想法吗?

【问题讨论】:

  • 也许这是一个愚蠢的问题:您处于集成模式还是经典模式?你都试过了吗?

标签: asp.net vb.net session servicestack ihttphandler


【解决方案1】:

将此添加到 LoginAppHost 配置方法是否可以解决您的问题?

Public Overrides Sub Configure(container As Funq.Container)
    'Set JSON web services to return idiomatic JSON camelCase properties
    ServiceStack.Text.JsConfig.EmitCamelCaseNames = True

    'code in the config options
    SetConfig(New EndpointHostConfig With
              {
                  .ServiceStackHandlerFactoryPath = "api", 'path where ServiceStack is hosted
                  .MetadataRedirectPath = "api/metadata" 'redirect path for /api to show meta data
              })
End Sub

我不太确定为什么不会从 web.config 文件中获取“配置”元素,但这应该明确处理位置/路径问题。此外,不确定您的环境,但这应该使用 Visual Studio 2012/IISExpress 和您的示例中的代码/配置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-26
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 2020-03-15
    相关资源
    最近更新 更多