Принудительная обратная связь Asp.Net - PullRequest
3 голосов
/ 12 мая 2010

Пожалуйста, посмотрите на следующее событие клика ...

 Protected Sub btnDownloadEmpl_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDownloadEmpl.Click
        Dim emplTable As DataTable = SiteAccess.DownloadEmployee_H()
        Dim d As String = Format(Date.Now, "d")
        Dim ad() As String = d.Split("/")
        Dim fd As String = ad(0) & ad(1)
        Dim fn As String = "E_" & fd & ".csv"
        Response.ContentType = "text/csv"
        Response.AddHeader("Content-Disposition", "attachment; filename=" & fn)
        CreateCSVFile(emplTable, Response.Output)
        Response.Flush()
        Response.End()
        lblEmpl.Visible = True
    End Sub

Этот код просто экспортирует данные из таблицы данных в файл CSV. Проблема здесь в том, что lblEmpl.Visible = true никогда не попадет, потому что этот код не вызывает обратную передачу на сервер. Даже если я добавлю строку кода lblEmpl.Visible = true в начало события click, строка выполняется нормально, но страница не обновляется. Как я могу это исправить?

Ответы [ 4 ]

4 голосов
/ 12 мая 2010

Эта строка:

lblEmpl.Visible = True

Никогда не получает удар, потому что эта строка:

Response.End()

Бросает ThreadAbortException

Я думаю, что более простой способ справиться с этим - создать простой компонент HttpHandler и «открыть» его во всплывающем окне. (Всплывающее окно на самом деле не должно открываться. В большинстве случаев браузер поймет, что это на самом деле загрузка, и заблокирует вкладку / окно.)

Исследуйте интерфейс IHttpHandler. Они на самом деле довольно просты в реализации.

Вот пример обработчика. Извините, что это заняло некоторое время, меня вызвали на встречу:

public class CensusHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        string fileName = String.Format(
            CultureInfo.CurrentUICulture,
            "E_{0:00}{1:00}.csv",
            DateTime.Today.Month,
            DateTime.Today.Day
            );

        context.Response.ContentType = "text/csv";
        context.Response.AddHeader(
            "Content-Disposition", String.Format(null, "attachment; filename={0}", fileName)
            );

        //Dump the CSV content to context.Response

        context.Response.Flush();
    }

    public bool IsReusable { get { return false; } }
}

ОК, попробуйте добавить событие javascript onclick для запуска загрузки:

<asp:Button ID="Clickety" runat="server" Text="Click Me!" OnClick="Clickety_Click"
    OnClientClick="window.open('Handler.ashx', 'Download');" />

Обычное событие OnClick вызовет ваш код обратной передачи. Событие javascript onclick (OnClientClick) запустит загрузку через HttpHandler.

1 голос
/ 12 мая 2010

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

  1. Создайте отдельную форму для всплывающего окна, чтобы создать CSV, переместите свою функцию в загрузку нового page.cs и отправьте ей строку строки запроса для своего dataID для экспорта.

    Protected Sub onLoad()
        Dim recordID As Integer = Request.Querystring("dID")
        Dim emplTable As DataTable = Nothing 
        Select Case recordID 
          case 1: emplTable = SiteAccess.DownloadEmployee_H() 
          case 2: emplTable = SiteAccess.DownloadManagers() 
        End Select 
        Response.Clear()
        Response.ContentType = "text/csv"
        Response.AddHeader("Content-Disposition", "attachment; filename=" & fn)
        CreateCSVFile(emplTable, Response.Output)
        Response.Flush()
        Response.End() 
        lblEmpl.Visible = True
    End Sub
    
  2. Запустите ваше всплывающее окно из свойства onClientClick кнопки или зарегистрируйте скрипт на обратной передаче.

    function fnPopUpCSV(expType)
    {        
    window.open('/popUpPage.aspx?dID=' + expType,'CSVwindow', 
    'width=300,height=200,menubar=yes,status=yes,
    location=yes,toolbar=yes,scrollbars=yes');
    }
    
    <asp:Button ID="btnGenEmplCSV" runat="server" Text="Generate Employee CSV"
    onClientClick="javascript:return fnPopUpCSV(1);" />
    
    <asp:Button ID="btnGenMgrCSV" runat="server" Text="Generate Manager CSV"
    onClientClick="javascript:return fnPopUpCSV(2);" />
    
1 голос
/ 12 мая 2010

Вы отправляете CSV вниз по потоку ответов и затем завершаете его. Поэтому, как только весь ваш код будет выполнен, сама страница больше не будет отправляться по потоку ответов и не будет обновляться в браузере.

Для того, чтобы достичь того, что вы хотите, вам нужно создать второй поток ответов. Самый простой способ сделать это - через новое окно / всплывающее окно браузера. После этого ваш CSV может загрузиться во всплывающем окне, а ваш первоначальный ответ на странице может остаться в исходном браузере.

0 голосов
/ 12 мая 2010

Просто создайте новую страницу с этим кодом на Page_Load

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) 
    Dim emplTable As DataTable = SiteAccess.DownloadEmployee_H()
    Dim d As String = Format(Date.Now, "d")
    Dim ad() As String = d.Split("/")
    Dim fd As String = ad(0) & ad(1)
    Dim fn As String = "E_" & fd & ".csv"
    Response.ContentType = "text/csv"
    Response.AddHeader("Content-Disposition", "attachment; filename=" & fn)
    CreateCSVFile(emplTable, Response.Output)
    Response.Flush()
    Response.End()
End Sub

Затем на исходной странице сделайте lblEmpl невидимым и зарегистрируйте скрипт, подобный следующему, чтобы открыть новое окно с вашим CSV.

var csvPageJS = string.Format("window.open ('{0}','mywindow');", ResolveUrl("~/MyCSVPage.aspx"));
  ClientScript.RegisterStartupScript(typeof(Page), "popup", csvPageJS, true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...