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();
}
}