Как вернуть несколько «документов» из приложения веб-форм? - PullRequest
1 голос
/ 12 марта 2012

У нас есть приложение webforms, которое генерирует параметрические документы. Пользователь предоставляет некоторую информацию, нажимает кнопку, и наш веб-сервис генерирует документы Word.

Служба работает для одного документа за раз, но не для пакетов. Мы хотим добавить возможность обрабатывать более одного документа. Теперь у нас есть код ниже, где contactIdsForLetters равен List<int>.

foreach (int contactId in contactIdsForLetters)
{
    string parameters = string.Format("ContactID~{0}", contactId);

    string defaultFilename = Reporting.Utilities.CreateDefaultFileName(outputformat);

    byte[] bytes = Reporting.Reports.CreateReport(selectedReportId, parameters, outputformat, out serviceCallWasSuccessful);

    if (!serviceCallWasSuccessful || bytes == null)
    {
        Reporting.Reports.LogReportActivity(selectedReportId, string.Empty, parameters, userLogin, false);

        return;
    }

    Reporting.Reports.LogReportActivity(selectedReportId, string.Empty, parameters, userLogin, true);

    Reporting.Utilities.SendResponse(defaultFilename, bytes);
}

При запуске вышеуказанного кода возвращается только один документ. Один документ обрабатывается (For-Each никогда не попадает ко второму элементу в contactIdsForLetters), появляется диалоговое окно с просьбой открыть или сохранить файл, и после нажатия кнопки «Открыть» Word открывается вместе с документом. Все происходит так, как должно, но мы не можем заставить For-Each обработать второй и последующие документы.

Пользователи хотят отдельную сессию Word для каждого возвращаемого документа. Последующие документы нужно будет открыть в своем собственном сеансе Word.

Как мне пройти по List<int>, отправить каждый int в службу по одному и открыть сеанс Word для каждого возвращенного документа?

Вот SendResponse () ...

public static void SendResponse(string defaultFilename, byte[] bytes)
{
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.ClearHeaders();
    HttpContext.Current.Response.Buffer = false;
    HttpContext.Current.Response.ContentType = "application/octet-stream";
    HttpContext.Current.Response.AppendHeader("Content-Disposition", string.Format("attachment; filename={0}", defaultFilename));
    HttpContext.Current.Response.AppendHeader("Content-Length", bytes.Length.ToString());
    HttpContext.Current.Response.BinaryWrite(bytes);
    HttpContext.Current.Response.Flush();
    HttpContext.Current.Response.End();
}

Ответы [ 2 ]

0 голосов
/ 13 марта 2012

ASP.NET работает поверх HTTP.

HTTP основан на основе запроса.

Каждый запрос возвращает ответ, если браузер может связаться с сервером. Этот ответ содержит поток (мы можем назвать его File в вашем случае). После того, как сервер сбросит этот поток (1-й файл), соединение запроса с сервером будет закрыто, и жизненный цикл запроса завершится, и все потоки, относящиеся к этому запросу, будут закрыты. Вот почему вы никогда не получите второй документ.

Вам нужно будет доставлять документы в сжатом контейнере, например, в виде zip-файла, чтобы все документы помещались в один поток. Сначала получите все документы, упакуйте их и отправьте ответ клиенту.

Надеюсь, это поможет.

ОБНОВЛЕНИЕ: Также вы можете захотеть использовать AJAX для генерации вызова javascript на сервер, возвращая разные ссылки для получения разных документов. Это все равно, что нажимать на разные невидимые ссылки, которые открывают разные документы после того, как пользователь нажимает одну кнопку или ссылку. Используя этот подход действительно легко достичь того, что вы хотите. Вы можете вызвать событие click для всех невидимых ссылок с помощью JavaScript.

0 голосов
/ 12 марта 2012

Не должно быть проблем с отправкой List<int> в службу и возвращением услуги List<byte[]>.

Я не знаю, что вы подразумеваете под "открыть сеанс Word". Я надеюсь, что вы не пытаетесь вызвать Word из приложения ASP.NET. Это не поддерживается, ненадежно и не очень хорошо работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...