Как: сохранить файл из веб-сервиса, не останавливая отображение страницы - PullRequest
1 голос
/ 09 января 2012

У меня есть контроллер с двумя страницами, Index и Download, при нажатии кнопки download он получает байт [] из службы, и я использую Response.BinaryWrite для сохранения файла. Проблема заключается в том, что при использовании Response.Clear он останавливает рендеринг страницы загрузки, но загружает файл успешно. Есть ли способ скачать файл и отобразить страницу?

Я использую .NET 4, ASP, Monorail Castle, C #

Мне известно, что с помощью MVC я могу использовать ActionResult и FileResult в качестве типов возврата для моих представлений, однако я ограничен использованием Monorail Castle, поскольку он является существующим проектом, владельцем которого я недавно стал, и не имею вес в изменении его технологии только сейчас.

Ниже приведен пример кода

public class MyController : Controller
{
    public void Index()
    {
        PropertyBag["includeZeroBalances"] = false;
        PropertyBag["toDate"] = DateTime.Today.ToShortDateString();
    }

    public void Download(bool includeZeroBalances, DateTime toDate)
    {
        MyProxy proxy = GetProxy();
        byte[] file = proxy.GetFile(includeZeroBalance, toDate);
        Response.Clear();
        Response.ContentType = "application/zip";
        Response.AppendHeader("Content-Disposition", "attachment; filename="TestFileName.zip");
        Response.BinaryWrite(file);
    }
}

Вот страница указателя

${Form.FormTag({@action: 'Download'})}
    <table>
        <tr>
            <td>${Form.LabelFor("toDate", "To Date (yyyy/mm/dd):")}</td>
            <td><input type="text" id="toDate" name="toDate" value="${?toDate}" /></td>
        </tr>
        <tr>
            <td>${Form.LabelFor("includeZeroBalances", "Include Zero Balances:")}</td>
            <td>${Form.CheckboxField("includeZeroBalances")}</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>${Form.Submit("Download", {@class: 'submitb'})}</td>
        </tr>
    </table>
${Form.EndFormTag()}

Вот страница загрузки

<table>
    <tr>
        <td>Your file has been downloaded successfully</td>
    </tr>
</table>

Ответы [ 2 ]

1 голос
/ 10 января 2012

Ответ, который я придумал, не такой общий, как хотелось бы, но это решение является функциональным.

public class MyController : Controller
{
    public void Index()
    {
        PropertyBag["includeZeroBalances"] = false;
        PropertyBag["toDate"] = DateTime.Today.ToShortDateString();
    }

    public void Download(bool includeZeroBalances, DateTime toDate)
    {
        MyProxy proxy = GetProxy();
        byte[] file = proxy.GetFile(includeZeroBalance, toDate);
        PropertyBag["downloadurl"] = "data:application/zip;base64," + System.Convert.ToBase64String(file);
    }
}

Вот страница индекса

${Form.FormTag({@action: 'Download'})}
    <table>
        <tr>
            <td>${Form.LabelFor("toDate", "To Date (yyyy/mm/dd):")}</td>
            <td><input type="text" id="toDate" name="toDate" value="${?toDate}" /></td>
        </tr>
        <tr>
            <td>${Form.LabelFor("includeZeroBalances", "Include Zero Balances:")}</td>
            <td>${Form.CheckboxField("includeZeroBalances")}</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>${Form.Submit("Download", {@class: 'submitb'})}</td>
        </tr>
    </table>
${Form.EndFormTag()}

Здесьстраница загрузки

<table>
    <tr>
        <td>Your file has been generated successfully. <a href="${downloadurl}">Click here</a> to download your file</td>
    </tr>
</table>

Вы также можете добавить javascript для автоматической загрузки файла в новом окне.

document.Ready(function()
{
    window.open("${downloadurl}");
});

Преимущества использования этой методологии для сохранения файлов: файлы не сохраняются насервер.Несколько меньшие накладные расходы при загрузке файлов размером более 300 КБ. Данные ответов не перезаписываются, поэтому представление будет отображаться в обычном режиме.

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

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

1 голос
/ 09 января 2012

«Правильный» способ сделать это - использовать многочастные ответы, к сожалению, некоторые браузеры не поддерживают их .

Что вы можете сделать, это использовать метаобновление, как это делают sourceforge и другие сайты. Для альтернатив см. Эти вопросы:

...