Подтвердить что ты не робот

Перенаправление/просмотр представления после сгенерированного файла загружается

У меня есть действие контроллера, которое загружает динамически сгенерированный файл:

    public ActionResult DownloadFile()
    {
        var obj = new MyClass { MyString = "Hello", MyBool = true };
        var ser = new XmlSerializer(typeof(MyClass));
        var stream = new MemoryStream();
        ser.Serialize(stream, obj);
        stream.Position = 0;

        Response.Clear();
        Response.AddHeader("Content-Disposition", "attachment; filename=myfile.xml");
        Response.ContentType = "application/xml";

        // Write all my data
        stream.WriteTo(Response.OutputStream);
        Response.End();

        return Content("Downloaded");
    }

Только для справки:

    public class MyClass
    {
        public string MyString { get; set; }
        public int MyInt { get; set; }
    }

Это работает, и файл (myfile.xml) загружен.
Однако сообщение "Скачано" не отправляется в браузер.

Аналогично, если я заменил return Content("Downloaded");
для return Redirect("www.something.com");
затем браузер перенаправляется до загрузки файла.

Как немного пре-амблема, пользовательское путешествие:

  • Пользователь заполняет форму в предыдущем представлении
  • Форма отправлена ​​
  • XML создается и загружается
  • Пользователь перенаправляется/отображается "Загруженный" вид (так что F5 не будет повторно размещать форму)
4b9b3361

Ответ 1

Каждый HTTP-запрос может иметь только один ответ - вы пытаетесь проникнуть в два (файл и страницу).

Обычно, когда вы отправляете HTTP-заголовок "Content-Disposition: attachment", браузер остается на текущей странице и открывает диалог сохранения файла (или автоматически сохраняет файл в ваших загрузках).

Вам придется изменить свою стратегию, если вы хотите предотвратить повторное представление формы. Я бы предложил немного javascript, чтобы отключить кнопку отправки формы и показать сообщение "Завершено" в наложении div?

Ответ 2

Как сказал Росс, вы можете вернуть только один ответ на HTTP-запрос. Что я делаю в этом случае:

  • Отправить запрос на сервер
  • Сервер создает файл и сохраняет его в некоторой структуре данных на стороне сервера (Cache, Usersession, TempData).
  • Сервер возвращает RedirectToAction() (шаблон POST, REDIRECT, GET)
  • Переадресованное действие возвращает вид с некоторым javascript, который
  • Запускает загрузку предварительно сгенерированного файла, устанавливая свойство window.location.href на специальное действие загрузки, которое отправляет файл обратно в браузер

Ответ 3

Вот как я перенаправлен после загрузки файла. Основной логикой является ожидание перенаправления до загрузки файла. Для этого рассчитывается ответ на стороне сервера, а перенаправление задерживается с использованием времени ответа на сервер + смещение.

Код сервера на стороне сервера:

[HttpPost]
public ActionResult GetTemplate()
    {
        return Json(new {Url = Url.Action("ReturnTemplate") });
    }

[HttpGet]
public ActionResult ReturnTemplate()
    {
        FileResult fileResult = // your file path ;
        return fileResult;
    }

Клиентский код:

<div id="btnGen" align="right"><button class="main-button"     id="generateTemplate" type="Submit"></div>

JavaScript:

$("#generateTemplate").click(function () {
    var startTime = (new Date()).getTime(), endTime;

        $.ajax({
            url: '@Url.Action("GetTemplate", "Controller")',
            type: 'POST',
            traditional: true,
            dataType: "json",
            contentType: "application/json",
            cache: false,
            data: JSON.stringify(),
            success: function (result) {
                endTime = (new Date()).getTime();
                var serverResponseTime = endTime - startTime + 500;
                setInterval(function () { Back() }, serverResponseTime);
                window.location = result.Url;
            }
        });
});

function Back() {
    window.location = '@Url.Action("Index","Controller")';
}