編集:
このエラーはlocation
、web.config での使用に関連しているようです。
完全に新しいプロジェクトで回避策を実行することができましたが、API の特定の場所を指定すると、再びエラーが表示されるようになりました。
Service Stack を追加する既存の ASP.NET Web アプリがあります。アプリは ASP.NET セッションに大きく依存しています。残念ながら、HttpContext.Current.Session が常に null であるため、Service Stack クラスのセッションにアクセスできません。
そのため、このスタック オーバーフローの回答から回避策の 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\
デフォルトの Service Stack 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 に変換された、回避策で使用される 2 つのクラスを次に示します。
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
ログイン.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
私はどのように進めるかについて完全に途方に暮れています。何かご意見は?