编辑:
该错误似乎与在web.config中使用location
有关。
我能够在一个全新的项目中使用变通方法,但是,一旦我为API指定了特定位置,我就开始再次看到错误。
我有一个现有的ASP.NET Web应用程序,我正在添加Service Stack。该应用程序在很大程度上依赖于ASP.NET Session。不幸的是,我无法访问我的服务堆栈类中的会话,因为HttpContext.Current.Session始终为null。
所以我从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处理程序时,一切正常(Sessions除外)。当我交换SessionHttpHandlerFactory
时,我收到了上述错误。
根据变通方法的说明,您必须将类型属性从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
这是我的服务堆栈实现。就像我说的,它使用默认的Service Stack 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
我完全不知道如何继续。有什么想法吗?
答案 0 :(得分:3)
将此添加到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
我不太清楚为什么'config'元素不会从web.config文件中获取,但是这应该明确地处理位置/路径问题。此外,不确定您的环境,但这应该使用Visual Studio 2012 / IISExpress与您的示例中的代码/配置。