Использовать ASP.Net для генерации кода управления сервером из .ashx - PullRequest
1 голос
/ 28 апреля 2010

Я пытаюсь взять существующий набор кода, который ранее находился на полной странице .aspx, и делаю то же самое в обработчике .ashx.

Код создал объект HtmlTable, добавил строки и ячейки в эти строки, затем добавил эту HTML-таблицу в коллекцию элементов управления .aspx, а затем добавил ее в div, который уже находился на странице.

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

HtmlTable выдает ошибки, когда я пытаюсь использовать свойство InnerHtml (говорит, что оно не поддерживается), и когда я пытаюсь использовать RenderControl, после создания сначала объекта TextWriter, а затем объекта HtmlTextWriter я получаю сообщение об ошибке, что страница не может быть нулевой. * * 1007

Кто-нибудь делал это раньше? Есть предложения?

Ответы [ 2 ]

2 голосов
/ 28 апреля 2010

* Последнее указано выше.

ОК, даже после обновления Мэтта есть обходной путь;)

Во-первых, мы должны использовать страницу с form внутри. В противном случае мы не сможем добавить ScriptManager элемент управления. Еще одна вещь: элемент управления ScriptManager должен быть первым элементом управления в форме. Дальше проще:

Page page = new Page();
Button button = new System.Web.UI.WebControls.Button
{
    ID = "btnSumbit",
    Text = "TextButton",
    UseSubmitBehavior = true
};
HtmlForm form = new HtmlForm
{
    ID="theForm"
};
ScriptManager scriptManager = new ScriptManager
{
    ID = "ajaxScriptManager"
};
form.Controls.Add(scriptManager);
form.Controls.Add(button);
page.Controls.Add(form);

using (StringWriter output = new StringWriter())
{
    HttpContext.Current.Server.Execute(page, output, false);

    context.Response.ContentType = "text/plain";
    context.Response.Write(output.ToString());
}

Это работает. Вывод довольно большой, поэтому я решил не включать его в свой ответ:)


На самом деле, есть обходной путь. Да, мы можем сделать элемент управления в обработчике.

Во-первых, нам нужна бесформенная страница. Потому что без него мы получим:

Элемент управления 'btnSumbit' типа 'Кнопка' должен быть помещен внутри тега формы с Runat = сервер. * * тысяча двадцать-одна

public class FormlessPage : Page
{
    public override void VerifyRenderingInServerForm(Control control)
    {
    }
}

Во-вторых, никто не может помешать нам создать экземпляр нашей FormlessPage страницы. А теперь давайте добавим туда элемент управления (я решил добавить Button элемент управления в качестве примера, но вы можете использовать любой).

FormlessPage page = new FormlessPage();
Button button = new System.Web.UI.WebControls.Button
{
    ID = "btnSumbit",
    Text = "TextButton",
    UseSubmitBehavior = true
};
page.Controls.Add(button);

В-третьих, давайте запишем вывод. Для этого мы используем HttpServerUtility.Execute метод:

Выполняет обработчик для указанного виртуальный путь в контексте текущий запрос System.IO.TextWriter захватывает вывод от выполненного обработчика и Логический параметр указывает, следует ли очистить System.Web.HttpRequest.QueryString и System.Web.HttpRequest.Form коллекции.

Вот код:

using (StringWriter output = new StringWriter())
{
    HttpContext.Current.Server.Execute(page, output, false);

    context.Response.ContentType = "text/plain";
    context.Response.Write(output.ToString());
}

Результат будет:

<input type="submit" name="btnSumbit" value="TextButton" id="btnSumbit" />

Кроме того, я могу порекомендовать статью ScottGu Совет / хитрость: крутая техника шаблонирования пользовательского интерфейса для использования с ASP.NET AJAX для сценариев без UpdatePanel . Надеюсь, там вы найдете много полезного.

1 голос
/ 28 апреля 2010

Другим вариантом является размещение HTTP-конвейера ASP.NET в вашем процессе, рендеринг страницы в поток и чтение HTML-кода, который необходимо отправить, из потока HttpListenerContext.Response.OutputStream после обработки страницы.

В этой статье есть детали: http://msdn.microsoft.com/en-us/magazine/cc163879.aspx

...