невозможно сохранить HttpPostedFileBase в переменную сеанса и использовать дважды - PullRequest
6 голосов
/ 20 января 2011

Доброе утро - я пытаюсь сохранить HttpPostedFileBase (который всегда будет простым CSV-файлом) в переменной сеанса, например так:

    [HttpPost]
    public ActionResult Index(HttpPostedFileBase importFile) {
        Session.Remove("NoteImport");
        var noteImport = new NoteImport { ImportFile = importFile, HeaderList = NoteService.HeaderList(importFile) };
        Session["NoteImport"] = noteImport;
        return RedirectToAction("FileNote");

    }

Как видите, я выгружаю importFile в свой NoteImportучебный класс.В настоящее время свойство ImportFile является общедоступным типом HttpPostedFileBase.

Когда я впервые использую это свойство в своем сервисе (метод, который создает список значений заголовков), у меня нет проблем:

    public List<string> HeaderList(HttpPostedFileBase fileStream) {
        var sr = new StreamReader(fileStream.InputStream);
        var headerString = sr.ReadLine();
        var headerArray = headerString.Split(',');
        var headerList = new List<string>();
        foreach (var header in headerArray) {
            if (!ValidateHeader(header))
                throw new InvalidDataException("Invalid header name: " + header);
            headerList.Add(header);
        }
        return headerList;
    }

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

Моя проблема с кодом ниже.Когда я вызываю ReadLine (), он ничего не получает из HttpPostedFileBase.

    public List<string> ImportFileStream(HttpPostedFileBase importFile) {
        var sr = new StreamReader(importFile.InputStream);
        var headerString = sr.ReadLine();
        var headerArray = headerString.Split(',');
        var cb = new DelimitedClassBuilder("temp", ",") { IgnoreFirstLines = 0, IgnoreEmptyLines = true, Delimiter = "," };
        foreach (var header in headerArray) {
            cb.AddField(header, typeof(string));
            cb.LastField.FieldQuoted = true;
            cb.LastField.QuoteChar = '"';
        }
        var engine = new FileHelperEngine(cb.CreateRecordClass());
        var dataTable = engine.ReadStreamAsDT(sr);
        var noteData = new List<string>();
        var jsonSerializer = new JsonSerializeDataRow();
        foreach (var row in dataTable.Rows) {
            var dataRow = row as DataRow;
            var jsonRow = jsonSerializer.Serialize(dataRow);
            noteData.Add(jsonRow);
        }
        return noteData;
    }

Я попытался закрыть HttpPostedFileBase;Я также установил позицию потока на 0. Кажется, ничего не происходит.У меня такое чувство, что мне нужно изменить его на другой тип перед сохранением в сеансе.

Любой совет ??

Спасибо!

Ответы [ 3 ]

5 голосов
/ 20 января 2011

Вы не можете сохранить HttpPostedFileBase в сеансе.Это просто не имеет смысла.Он содержит поток, указывающий на содержимое файла из потока HTTP-запросов, который является мусором, собираемым в конце запроса.Вам нужно сериализовать его в какой-то пользовательский объект перед сохранением в сеансе.Например:

public class MyFile
{
    public string Name { get; set; }
    public string ContentType { get; set; }
    public byte[] Contents { get; set; }
}

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

2 голосов
/ 09 февраля 2014

если вы используете HttpPostedFileBase, вам нужно сначала его клонировать,
я использовал код из этого git
, вам просто нужно добавить это как класс в ваше пространство имен:

public static class HttpPostedFileBaseExtensions
{
    public static Byte[] ToByteArray(this HttpPostedFileBase value)
    {
        if (value == null)
            return null;
        var array = new Byte[value.ContentLength];
        value.InputStream.Position = 0;
        value.InputStream.Read(array, 0, value.ContentLength);
        return array;
    }
}

теперь вы можете читать HttpPostedFileBase следующим образом:

private static void doSomeStuff(HttpPostedFileBase file)
{
    try
    {
        using (var reader = new MemoryStream(file.ToByteArray()))
        {
            // do some stuff... say read it to xml
            using (var xmlTextReader = new XmlTextReader(reader))
            {                    

            }
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

после использования вы все равно можете написать в своем основном коде:

file.SaveAs(path);

и он сохранит егофайл.

0 голосов
/ 20 января 2011

HttpPostedFile читает напрямую из потока HTTP-запросов.
Не подходит для повторного использования.

...