2012-02-02 4 views
4

Я пытаюсь передать массив/IEnumerable из Guids к 'GET' Для MVC метод, который выглядит следующим образом:Pass JavaScript/JSON массив MVC 'GET' Метод

[HttpGet] 
public ActionResult ZipResults(IEnumerable<Guid> ids) 
{ 
    using(var zip = new Zip()) 
    { 
     foreach(var id in ids) 
     { 
      var stream = GetDataStream(id); 
      zip.AddEntry("filename.txt", stream); 
     } 
    } 

    var outputStream = new MemoryStream(); 
    zip.Save(outputStream); 

    return FileStreamResult(outputStream, "application/octet-stream"){ 
     FileDownloadName = "Results.zip" }; 
} 

И мой Javascript выглядит это:

$('the-button').click(function(){ 

    // 1. Get the guids from a table and add to javascript array (works fine) 
    // 2. Grey-out screen and show processing indicator (works fine) 

    // 3. This is how I'm calling the "ZipResults" action: 
    $.ajax({ 
     url: '@Url.Action("ZipResults", "TheController")', 
     type: 'GET', 
     data: $.toJSON({ ids: _ids }), 
     dataType: 'json', 
     contentType: 'application/json;charset=utf-8', 
     traditional: true, 
     success: function(){ 
      // Undo the grey-out, and remove processing indicator 
     }, 
     error: function(){ 
     } 
    }); 
}); 

Мое предположение заключается в том, что это откроет диалоговое окно загрузки в браузере. Как бы то ни было, массив javascript, передаваемый контроллеру, является нулевым (на стороне сервера он корректно работает на стороне клиента). Кроме того, это работает отлично с «POST», однако, метод а «POST» использовали этот путь не будет форсировать диалог загрузки ...

Открыт для предложений :)

ответ

4

Вам следует избегать отправки запросов JSON с помощью GET. Попробуйте так:

var _ids = [ 
    'e2845bd4-9b3c-4342-bdd5-caa992450cb9', 
    '566ddb9d-4337-4ed7-b1b3-51ff227ca96c', 
    '25bc7095-a12b-4b30-aabe-1ee0ac199594' 
]; 

$.ajax({ 
    url: '@Url.Action("ZipResults", "TheController")', 
    type: 'GET', 
    data: { ids: _ids }, 
    dataType: 'json', 
    traditional: true, 
    success: function() { 
     // Undo the grey-out, and remove processing indicator 
    }, 
    error: function() { 

    } 
}); 

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

Так что, если вы хотите скачать файл, не нужно AJAX. Вы можете использовать простой якорь:

@Html.ActionLink("download zip", "ZipResults", "TheController", null, new { id = "download" }) 

, а затем:

$(function() { 
    $('#download').click(function() { 
     var _ids = [ 
      'e2845bd4-9b3c-4342-bdd5-caa992450cb9', 
      '566ddb9d-4337-4ed7-b1b3-51ff227ca96c', 
      '25bc7095-a12b-4b30-aabe-1ee0ac199594' 
     ]; 

     var url = this.href; 
     for (var i = 0; i < _ids.length; i++) { 
      if (url.indexOf('?') > 0) { 
       url += '&ids=' + encodeURIComponent(_ids[i]); 
      } else { 
       url += '?ids=' + encodeURIComponent(_ids[i]); 
      } 
     } 

     window.location.href = url; 

     return false; 
    }); 
}); 
+1

как всегда, вы, вероятно, прав насчет того, чтобы не делать этого с ajax ... – Didaxis

+0

@ErOx, абсолютно. Не используйте AJAX, если вы хотите загрузить файлы. –

2

Проблема заключается в том, что ПОЛУЧИТЬ Безразлично Получить тело запроса. Я подозреваю, что если вы посмотрите на запрошенный клиентом запрос, вы обнаружите, что он пытается перетащить перечислимую строку запроса ....

Post -> Redirect выглядит как лучший способ действий здесь.

+0

Я пытался пост -> перенаправлять раньше, но затем передавая поток в RedirectToAction дал мне ошибку: «Таймауты не поддерживаемый в этом потоке ». – Didaxis

+0

Да. Чтобы сделать это с помощью GET, я думаю, вам нужно будет отправлять данные как параметры запроса, а не как тело запроса, а затем обрабатывать параметры запроса на стороне сервера. – dgvid

Смежные вопросы