Рендеринг ASPX-страницы во время выполнения из базы данных

Предполагая код ниже:

public class DynamicAspxHandler : IHttpHandler {
    bool IHttpHandler.IsReusable { get { return false; } }

    void IHttpHandler.ProcessRequest(HttpContext httpContext) {
        string aspxContent = PlainASPXContent();
        Page page = CreatePage(httpContext, aspxContent);
        page.ProcessRequest(httpContext);
    }

    Page CreatePage(HttpContext context, string aspxContent) {
        // How to implement this?
    }
}

Как я могу реализовать метод CreatePage для создания экземпляра страницы на основе содержимого простой строки ASPX?

Обратите внимание, что сама строка ASPX может содержать ссылку на уже существующую MasterPage на диске.

Я понимаю, что с этим должны быть огромные проблемы с производительностью, но на данном этапе я просто хочу знать, как я могу это сделать. Очевидно, мне придется кэшировать результат.

Благодарю.

2 ответа

Решение

Путь, по которому вы пытаетесь пойти, - это, по сути, загрузка файлов ASPX из другого механизма хранения, чем файловая система веб-сервера. Вы начали реализовывать часть этого, но на самом деле вам даже не нужен собственный HttpHandler для этого - в ASP.NET существует механизм для указания других источников фактической разметки ASPX.

Он называется VirtualPathProvider, и он позволяет вам заменить функциональность по умолчанию для загрузки файлов с диска, скажем, загрузки их с SQL Server или где-либо еще, что имеет смысл. Затем вы можете воспользоваться всеми встроенными средствами компиляции и кэширования, которые ASP.NET использует самостоятельно.

Ядро функциональности находится в методе GetFile и Open() VirtualFile:

public override VirtualFile GetFile(string virtualPath)
{
    //lookup ASPX markup
    return new MyVirtualFile(aspxMarkup);
}

//...

public class MyVirtualFile : VirtualFile
{
    private string markup;

    public MyVirtualFile(string markup)
    {
        this.markup = markup;
    }

    public override Stream Open()
    {
        return new StringReader(this.markup);
    }
}

Обратите внимание, что сегодня использование пользовательского VirtualPathProvider требует полного доверия. Тем не менее, скоро ASP.NET 4.0 будет доступен, и он поддерживает VPP при среднем доверии.

Один из способов сделать это - создать подкласс VirtualPathProvider и установить его как HostingEnvironment.VirtualPathProvider, вызвав HostingEnvironment.RegisterVirtualPathProvider. Вам придется переопределить несколько методов. Наиболее важным из них является GetFile(). Система сборки позаботится о кэшировании.

Другие вопросы по тегам