使用 System.Web.Hosting 在 ASP.Net 应用程序中托管页面

发布于 2024-12-01 05:59:05 字数 4925 浏览 0 评论 0原文

我想知道是否可以在当前运行的 Web 应用程序的目录内托管页面。我想要这个功能,以便我可以动态添加页面/程序集而无需回收应用程序池。我认为可以这样做,并且我认为我已经接近了,但是当我尝试加载页面时,我不断收到服务器错误:路径“/App_GlobalResources/”映射到此应用程序外部的目录,该目录不是支持。

我正在将所有当前程序集和其他几个程序集加载到新的 appDomain 中,然后尝试处理 httpWorkerRequest。 我知道,我提供的代码很差,但我只是想让这个东西呼吸起来。

Public Class ApplicationHostHelper
    Private _appDomain As AppDomain
    Public Function ConstructNewAppDomain() As AppDomain
        Dim testDirectory As String = "<appDirectory>\TestDomains\TestDomain"

        Dim args As New AppDomainSetup()
        args.ApplicationBase = testDirectory
        args.ConfigurationFile = "Web.Config"


        Dim assemblyName As String
        Dim assemblyNames As New List(Of String)()
        For Each ass As System.Reflection.Assembly In AppDomain.CurrentDomain.GetAssemblies()
            assemblyName = String.Empty
            If Not ass.GetType().Namespace.Equals("System.Reflection.Emit", System.StringComparison.InvariantCultureIgnoreCase) Then assemblyName = System.IO.Path.GetFileName(ass.Location)
            If Not IsSystemDependencyName(assemblyName) AndAlso Not assemblyName = String.Empty Then
                If Not System.IO.File.Exists(testDirectory & "\" & assemblyName) Then
                    System.IO.File.Copy(ass.Location, testDirectory.TrimEnd("\"c) & "\" & assemblyName, True)
                    If Not assemblyNames.Contains(assemblyName) Then assemblyNames.Add(assemblyName)
                End If

            End If
        Next
        Dim splitPath() As String = System.Reflection.Assembly.GetExecutingAssembly.CodeBase.Replace("file:///", "").Split("/"c)
        Dim basePath As String = Nothing
        For x As Int32 = 0 To splitPath.Length - 3
            basePath += splitPath(x) & "\"
        Next
        basePath &= "Web.config"
        Dim newWebConfigPath As String = testDirectory.TrimEnd("\"c) & "\" & "Web.config"
        If System.IO.File.Exists(basePath) AndAlso Not System.IO.File.Exists(newWebConfigPath) Then System.IO.File.Copy(basePath, newWebConfigPath)

        Dim retval As AppDomain = AppDomain.CreateDomain("CustomPagesDomain", Nothing, args)
        retval.SetData(".appId", "CustomPagesDomain")
        retval.SetData(".appDomain", "*")
        retval.SetData(".appPath", testDirectory)
        retval.SetData(".appVPath", "/")
        retval.SetData(".domainId", "CustomPagesDomain")
        retval.SetData(".hostingVirtualPath", "/")
        retval.SetData(".hostingInstallDir", testDirectory)
        _appDomain = retval
        Return retval
    End Function

    Public Function LoadPage(ByVal textWriter As System.IO.TextWriter) As AppDomain
        Dim myHost As CustomPagesHost = CType(CreateApplicationHost(), CustomPagesHost)
        myHost.ProcessRequest("StatsReport.aspx", textWriter)
        Return _appDomain
    End Function

    Public Function CreateApplicationHost() As Object
        Dim tempAppDomain As AppDomain = ConstructNewAppDomain()
        Dim oh As System.Runtime.Remoting.ObjectHandle = tempAppDomain.CreateInstance(GetType(CustomPagesHost).Module.Assembly.FullName, GetType(CustomPagesHost).FullName)
        Return oh.Unwrap()
    End Function


    Public Shared Function IsSystemDependencyName(ByVal potentialSystemAssemblyName As String) As Boolean
        If potentialSystemAssemblyName.ToLower = "system" Then Return True
        If potentialSystemAssemblyName.ToLower = "mscorlib" Then Return True
        If potentialSystemAssemblyName.Split("."c)(0).ToLower = "system" Then Return True
        If potentialSystemAssemblyName.Split("."c)(0).ToLower = "microsoft" Then Return True
        Return False
    End Function

End Class

Public Class CustomPagesHost
    Inherits MarshalByRefObject
    Public Sub ProcessRequest(ByVal page As String, ByVal textWriter As System.IO.TextWriter)

        Dim hwr As HttpWorkerRequest = New System.Web.Hosting.SimpleWorkerRequest(page, Nothing, textWriter)
        HttpRuntime.ProcessRequest(hwr)
    End Sub
End Class


Private Sub _loadAppDomain_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _loadAppDomain.Click
Dim cHelper As New ApplicationHostHelper()
        Dim testDomain As AppDomain = Nothing
        Dim textWriter As System.IO.TextWriter
        Dim ms As New System.IO.MemoryStream()
        textWriter = New System.IO.StreamWriter(ms)
        Try

            testDomain = cHelper.LoadPage(textWriter)
            textWriter.Flush()
            ms.Position = 0
            _status.Text = New System.IO.StreamReader(ms).ReadToEnd()

        Catch ex As Exception
            _status.Text = ex.ToString()
        Finally
            If Not testDomain Is Nothing Then
                AppDomain.Unload(testDomain)
                DumpFiles("<appDirectory>\TestDomains\TestDomain\")
            End If

        End Try
End Sub

我非常感谢有关此主题的任何帮助。我似乎无法再取得进步了。

谢谢!

I would like to know if it is possible to host pages inside of a directory in a currently running web application. I would like this functionality so that I can dynamically add pages/assemblies without recycling the app pool. I think it is possible to do so and I think I am getting close, but I keep getting a server error when I try to load up a page: The path '/App_GlobalResources/' maps to a directory outside this application, which is not supported.

I am loading all the current assemblies and a couple other ones into a new appDomain and then trying to process a httpWorkerRequest.
The code I am providing is poor, I know, but I am just trying to get this thing to breathe.

Public Class ApplicationHostHelper
    Private _appDomain As AppDomain
    Public Function ConstructNewAppDomain() As AppDomain
        Dim testDirectory As String = "<appDirectory>\TestDomains\TestDomain"

        Dim args As New AppDomainSetup()
        args.ApplicationBase = testDirectory
        args.ConfigurationFile = "Web.Config"


        Dim assemblyName As String
        Dim assemblyNames As New List(Of String)()
        For Each ass As System.Reflection.Assembly In AppDomain.CurrentDomain.GetAssemblies()
            assemblyName = String.Empty
            If Not ass.GetType().Namespace.Equals("System.Reflection.Emit", System.StringComparison.InvariantCultureIgnoreCase) Then assemblyName = System.IO.Path.GetFileName(ass.Location)
            If Not IsSystemDependencyName(assemblyName) AndAlso Not assemblyName = String.Empty Then
                If Not System.IO.File.Exists(testDirectory & "\" & assemblyName) Then
                    System.IO.File.Copy(ass.Location, testDirectory.TrimEnd("\"c) & "\" & assemblyName, True)
                    If Not assemblyNames.Contains(assemblyName) Then assemblyNames.Add(assemblyName)
                End If

            End If
        Next
        Dim splitPath() As String = System.Reflection.Assembly.GetExecutingAssembly.CodeBase.Replace("file:///", "").Split("/"c)
        Dim basePath As String = Nothing
        For x As Int32 = 0 To splitPath.Length - 3
            basePath += splitPath(x) & "\"
        Next
        basePath &= "Web.config"
        Dim newWebConfigPath As String = testDirectory.TrimEnd("\"c) & "\" & "Web.config"
        If System.IO.File.Exists(basePath) AndAlso Not System.IO.File.Exists(newWebConfigPath) Then System.IO.File.Copy(basePath, newWebConfigPath)

        Dim retval As AppDomain = AppDomain.CreateDomain("CustomPagesDomain", Nothing, args)
        retval.SetData(".appId", "CustomPagesDomain")
        retval.SetData(".appDomain", "*")
        retval.SetData(".appPath", testDirectory)
        retval.SetData(".appVPath", "/")
        retval.SetData(".domainId", "CustomPagesDomain")
        retval.SetData(".hostingVirtualPath", "/")
        retval.SetData(".hostingInstallDir", testDirectory)
        _appDomain = retval
        Return retval
    End Function

    Public Function LoadPage(ByVal textWriter As System.IO.TextWriter) As AppDomain
        Dim myHost As CustomPagesHost = CType(CreateApplicationHost(), CustomPagesHost)
        myHost.ProcessRequest("StatsReport.aspx", textWriter)
        Return _appDomain
    End Function

    Public Function CreateApplicationHost() As Object
        Dim tempAppDomain As AppDomain = ConstructNewAppDomain()
        Dim oh As System.Runtime.Remoting.ObjectHandle = tempAppDomain.CreateInstance(GetType(CustomPagesHost).Module.Assembly.FullName, GetType(CustomPagesHost).FullName)
        Return oh.Unwrap()
    End Function


    Public Shared Function IsSystemDependencyName(ByVal potentialSystemAssemblyName As String) As Boolean
        If potentialSystemAssemblyName.ToLower = "system" Then Return True
        If potentialSystemAssemblyName.ToLower = "mscorlib" Then Return True
        If potentialSystemAssemblyName.Split("."c)(0).ToLower = "system" Then Return True
        If potentialSystemAssemblyName.Split("."c)(0).ToLower = "microsoft" Then Return True
        Return False
    End Function

End Class

Public Class CustomPagesHost
    Inherits MarshalByRefObject
    Public Sub ProcessRequest(ByVal page As String, ByVal textWriter As System.IO.TextWriter)

        Dim hwr As HttpWorkerRequest = New System.Web.Hosting.SimpleWorkerRequest(page, Nothing, textWriter)
        HttpRuntime.ProcessRequest(hwr)
    End Sub
End Class


Private Sub _loadAppDomain_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _loadAppDomain.Click
Dim cHelper As New ApplicationHostHelper()
        Dim testDomain As AppDomain = Nothing
        Dim textWriter As System.IO.TextWriter
        Dim ms As New System.IO.MemoryStream()
        textWriter = New System.IO.StreamWriter(ms)
        Try

            testDomain = cHelper.LoadPage(textWriter)
            textWriter.Flush()
            ms.Position = 0
            _status.Text = New System.IO.StreamReader(ms).ReadToEnd()

        Catch ex As Exception
            _status.Text = ex.ToString()
        Finally
            If Not testDomain Is Nothing Then
                AppDomain.Unload(testDomain)
                DumpFiles("<appDirectory>\TestDomains\TestDomain\")
            End If

        End Try
End Sub

I would really appreciate any help on this topic. I can't seem to make progress anymore.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文