Подход к нацеливанию обработчика HTTP из нажатия кнопки

Основная цель здесь — нацелить обработчик на загрузку просматриваемого файла.

Есть два разных состояния файла, одно где он уже сохранен в базе данных, затем следующие параметры обработчику через строку запроса

COIHandler.axd?Action=preview_saved&letterId=xxxx

or

тот, который еще не был сохранен, в котором я сохраняю его в сеансе и нацеливаю обработчик следующим образом

COIHandler.axd?Action=preview_unsaved

то обработчик будет обрабатывать очистку сеанса после того, как я закончу. Любые мысли о том, как это сделать. Все еще новичок в обработчиках http.

ПОЯСНЕНИЕ

У меня есть свойство OnClientClick в моей подклассовой версии класса Button, которое позволяет мне добавлять к нему javascript, который будет выполняться на стороне клиента. Вот где я хочу, чтобы таргетинг происходил.

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

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


person Matthew Cox    schedule 14.02.2011    source источник
comment
Как насчет использования Button.PostBackURL вместо моего пользовательского свойства javascript? Просто укажите его обработчику, и он не должен перенаправлять или что-то еще, просто обслуживать запрос.   -  person Matthew Cox    schedule 14.02.2011


Ответы (3)


В ответ на комментарий Yads вы можете использовать обработчик нажатия кнопки на своей странице, чтобы загрузить файл без необходимости во всплывающем окне или отдельном обработчике HTTP.

protected void btnDownload_OnClick(object sender, EventArgs args)
{       
    PDFContentData data = GeneratePDFData(); //parses strings from some source (as mentioned in comments)
    WebFileUtil.InvokePDFDownload(Page.Context, data);
}

public static class WebFileUtil
{
    public static void InvokePDFDownload(HttpContext context, PDFContentData data)
    {
        context.Response.Clear();
        context.Response.ClearContent();
        context.Response.ClearHeaders();

        FileStore.generateDocument(data, context.Response.OutputStream);

        context.Response.ContentType = "application/pdf"; 
        context.Response.ContentEncoding = System.Text.Encoding.UTF8;
        context.Response.AddHeader("Content-Disposition", String.Format("attachment;filename={0}_Documenth.pdf", DateTime.Now.ToShortDateString()));
        context.Response.End();
    }
}
person cweston    schedule 14.02.2011
comment
Кажется, не видел моего ответа на этот комментарий. Это не лучший подход в моей ситуации, потому что эта функция обслуживания файлов PDF встречается на многих разных страницах, отличных от рассматриваемой. Таким образом, этот подход приведет к решению для копирования и вставки. - person Matthew Cox; 14.02.2011
comment
@ Мэтью Кокс - Ах, да, я не увидел ваш комментарий вовремя. Вы можете создать общий класс веб-утилиты для этого и при этом иметь возможность повторного использования. См. мое изменение кода выше. - person cweston; 14.02.2011

Ваш обработчик на самом деле будет .ashx. В остальном ваш подход кажется хорошим. Вы можете проверить контекст, который передается в метод PrcoessRequest.

public void ProcessRequest(HttpContext context)
{
    switch(context.Request.QueryString["Action"].ToLower())
    {
       case "preview_saved":
           //do stuff for saved
       case "preview_unsaved":
           //do stuff for unsaved
     }
}

ОБНОВЛЕНИЕ Если вам нужен центральный обработчик, вы либо захотите перенаправить пользователя в конце вызова, и в этом случае вы также захотите передать параметр returnUrl в строке запроса. Тогда вы можете просто сделать context.Response.Redirect(context.Request.QueryString["returnUrl"]). Или, если вы хотите, чтобы страница сохраняла свое состояние, вам придется сделать Ajax-вызов своему обработчику.

person Vadim    schedule 14.02.2011
comment
Я написал деформатор для обработки контекста, но более или менее придерживаюсь такого подхода. Я собираюсь уточнить вопрос, потому что мне только что пришло в голову, что он недостаточно ясен. - person Matthew Cox; 14.02.2011
comment
@ Мэтью, тогда почему бы просто не обработать это на странице в обработчике кликов сервера. Зачем вам нужен другой обработчик для этого? - person Vadim; 14.02.2011
comment
Хороший вопрос. Требуется больше контекста =D Причина в том, что обслуживаемый файл представляет собой PDF-файл, созданный из строк html. Эта функция используется в разных местах продукта, а не только на этой странице. Поэтому я сделал обработчик, который обслуживает файлы PDF. - person Matthew Cox; 14.02.2011

Во-первых, большое спасибо за все возможные решения, которые они помогли выйти за рамки стандартного.

Я нашел уникальное решение, которым, как я думал, я поделюсь.

  1. Я размещаю невидимый iframe в html-разметке своей страницы.

  2. затем я устанавливаю свойство OnClientClick в моей кнопке загрузки элемента управления сервером (это позволяет мне отображать строку параметра в атрибуте onclick HTML)

    Я установил для этого свойства метод javascript, который воплощает рекурсивный алгоритм для перехода к верхнему родительскому фрейму страницы. Как только он достигает этой точки, я использую простой селектор JQuery для поиска iframe, о котором я говорил на шаге 1. (The причина рекурсии заключается в том, чтобы поддерживать поддержку главных страниц, где у вас будут фреймы внутри фреймов).

  3. Задайте для атрибута src iframe целевой обработчик HTTP. Применяемое поведение заставляет iframe загружать запрошенный источник ... но в этом случае это обработчик, и, поскольку все это было сделано изначально из прямого ввода пользователя (через нажатие кнопки «Загрузить»), у вас даже не будет проблемы получения желтой полосы с IE7+

  4. Обработчик обслуживает запрос, и файл передается в браузер.

Ура!

person Matthew Cox    schedule 14.02.2011