Ошибка файла не найдена с действием контроллера FileStreamResult - PullRequest
0 голосов
/ 25 августа 2010

У меня есть действие контроллера, объявленное следующим образом:

[Authorize(Order = 0, Roles = "Requester,Controller,Installer")]
public FileStreamResult ExportJobCards()

Тело этого метода создает коллекцию строк CSV и пытается вернуть их в виде файла следующим образом:

using (var sw = new StreamWriter(new MemoryStream()))
{
    foreach (var line in lines)
    {
        sw.WriteLine(line);
    }
    return new FileStreamResult(sw.BaseStream, "text/csv");
}  

Когда я запрашиваю это действие, используя следующую ссылку действия ...

Html.ActionLink("Export to Excel", "ExportJobCards")

... метод экспорта выполняется правильно, то есть все необходимые данные CSV присутствуют в коллекции lines вкод выше, но я получаю File Not Found ошибку, отображаемую в качестве конечного результата.

РЕДАКТИРОВАТЬ: В соответствии с наблюдением Томми, я переместил return из using, и теперь я получаю файл, но файл пуст.Новый код, который на самом деле создает файл с возможностью пустого файла:

var sw = new StreamWriter(new MemoryStream());            
foreach (var line in lines)
{
    sw.WriteLine(line);
}
sw.Flush();
return new FileStreamResult(sw.BaseStream, "text/csv");  

Ответы [ 2 ]

2 голосов
/ 25 августа 2010

При текущей настройке оператор Using удаляет StringWriter до завершения возврата, что приводит к ошибке нулевой ссылки / файла не найден.Удалите оператор using или задайте для StringWriter другую переменную перед выходом из системы, и вам следует продолжать избавляться от ошибки File Not Found.

Теперь подумайте о второй проблеме, рассматривая потоки памяти какрезультаты файлового потока, вам может потребоваться изменить ваш возврат на этот

sw.BaseStream.seek(0, SeekOrigin.Begin)
return new FileStreamResult(sw.BaseStream, "text/csv"); 

, так как при возврате указатель все еще находится в конце потока.

0 голосов
/ 25 августа 2010

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

  1. использовать построитель строк, а не потоковый писатель
  2. получить вашу строку от сборщика
  3. используйте статический метод System.Text.UnicodeEncoding.Unicode.GetBytes (string), чтобы получить байтовый массив
  4. Передать байтовый массив FileContentResult

Поскольку вы все равно должны написать этот кодпроще всего было бы создать новый FileStringResult, который наследуется от базового FileResult, который может принимать строку или построитель строк.Переопределите WriteFile (ответ HttpResponseBase), чтобы выполнить преобразование строки в байт [], и вставьте его в ответ.Взгляните на класс FileStreamResult из источников MVC, он очень маленький и простой в использовании.

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