asp.net mvc, обслуживающий txt, усекается

Я пытаюсь обработать текстовый файл из базы данных с помощью действия. Действие заключается в следующем:

public ActionResult ATxt()
{
    var articulos = _articulosService.ObteTotsArticles();
    return File(CatalegATxt.ATxt(articulos), "text/plain");
}

и класс CatalegATxt:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using WebDibaelsaMVC.DTOs.Busqueda;

namespace WebDibaelsaMVC.TxtLib
{
    public static class CatalegATxt
    {
         public static Stream ATxt(IEnumerable<ArticuloBusquedaDTO> articles)
         {
            var stream = new MemoryStream();
            var streamWriter = new StreamWriter(stream, Encoding.UTF8);
            foreach (ArticuloBusquedaDTO article in articles)
            {
                streamWriter.WriteLine(article.ToStringFix());
            }
            stream.Seek(0, SeekOrigin.Begin);
            return stream;
        }

        public static string ToStringFix(this ArticuloBusquedaDTO article)
        {
            string result = "";
            result += article.CodigoArticulo.PadRight(10, ' ').Substring(0, 10);
            result += article.EAN.Trim().PadLeft(13, '0').Substring(0, 13);
            result += article.NombreArticulo.PadRight(100, ' ').Substring(0, 100);
            result += article.Marca.PadRight(100, ' ').Substring(0, 100);
            result += article.Familia.PadRight(50, ' ').Substring(0, 50);
            result += article.PrecioCesion.ToStringFix();
            result += article.PVP.ToStringFix();
            return result;
        }

        private static string ToStringFix(this double numero)
        {
            var num = (int)Math.Round(numero * 100, 0);
            string result = num.ToString().PadLeft(10, '0');
            return result;
        }
    }
}

он просто записывает строки файла, основываясь на материалах, которые я получил из базы данных. Но когда я смотрю на файл, он выглядит усеченным. Файл составляет около 8 МБ. Я также пытался конвертировать в byte[] перед возвращением из ATxt с тем же результатом.

Любая идея?

Спасибо,

Карлес

Обновление: я также пытался обслуживать XML из того же контента, и он также усекается. Он не усекается на данных (я думал, что это мог быть символ EOF), но он усекается в середине метки...

3 ответа

Решение

У меня была точно такая же проблема. Текстовый файл всегда будет возвращен как усеченный.

Мне пришло в голову, что это может быть "смывной" проблемой, и это действительно так. Буфер писателя не был очищен в конце операции - так как здесь нет использования блока или вызова Close(), который бы автоматически очищался.

Вам нужно позвонить:

streamWriter.Flush();

прежде чем MVC берет на себя поток.

Вот как должен выглядеть ваш метод:

 public static Stream ATxt(IEnumerable<ArticuloBusquedaDTO> articles)
 {
    var stream = new MemoryStream();
    var streamWriter = new StreamWriter(stream, Encoding.UTF8);
    foreach (ArticuloBusquedaDTO article in articles)
    {
        streamWriter.WriteLine(article.ToStringFix());
    }
    // Flush the stream writer buffer
    streamWriter.Flush();
    stream.Seek(0, SeekOrigin.Begin);
    return stream;
}

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

Мирослав

Почему вы используете ActionResult?

ASP.NET MVC 1 имеет FileStreamResult только для того, что вы делаете. Он ожидает объект Stream и возвращает его.

public FileStreamResult Test()
{
  return new FileStreamResult(myMemoryStream, "text/plain");
}

Должно работать хорошо для того, что вы хотите сделать. Нет необходимости делать какие-либо преобразования.

В вашем случае просто измените ваш метод на это:

public FileStreamResult ATxt()
{
    var articulos = _articulosService.ObteTotsArticles();
    return new FileStreamResult(CatalegATxt.ATxt(articulos), "text/plain");
}

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

public static byte[] ATxt(IEnumerable<ArticuloBusquedaDTO> articles)
{
   using(var stream = new MemoryStream())
   {
        var streamWriter = new StreamWriter(stream, Encoding.UTF8);
        foreach (ArticuloBusquedaDTO article in articles)
        {
            streamWriter.WriteLine(article.ToStringFix());
        }

        return stream.ToArray();
    }
}
Другие вопросы по тегам