2014-12-05 3 views
1

У моего сервера есть API для загрузки файлов и преобразования их в PDF. Прямо сейчас, файл загружается, сохраняется на диск и затем преобразуется. Смотрите ниже код (урезана):Получить имя загружаемого файла при потоковой загрузке

public class ConversionController : ApiController { 
    public async Task<HttpResponseMessage> PostData() { 
     var root = HttpContext.Current.Server.MapPath("~/App_Data"); 
     var provider = new MultipartFormDataStreamProvider(root); 
     await Request.Content.ReadAsMultipartAsync(provider); 

     var file = provider.FileData.First(); 
     var originalName = file.Headers.ContentDisposition.FileName; 
     var fileStream = new FileStream(file.LocalFileName, FileMode.Open, FileAccess.Read); 

     // convert file stream and return the PDF response ... 
    } 
} 

Как вы можете видеть, я прочитал файл на диск, но затем сразу же получить поток для того, чтобы я мог кормить его к нашей функции преобразования (которая принимает поток) , Это кажется пустой тратой для сохранения файла на диск каждый раз. Поэтому вместо ReadAsMultipartAsync(), который сохраняет на диск, я могу использовать ReadAsStreamAsync(), который даст мне поток, который я могу передать непосредственно функции преобразования.

Проблема, с которой я столкнулся с ReadAsMultipartAsync(), заключается в том, что я не могу понять, как получить исходное имя файла без использования экземпляра MultipartFileData. Я знаю, что имя приходит с запросом как часть тела, но я не могу понять, как получить к нему доступ. Как я могу получить имя загруженного файла, не записывая загруженный файл на диск?

+0

Посмотрите на http://stackoverflow.com/questions/12586590/request-content-readasmultipartasync-error. Не дублированный вопрос, но пример кода в первом ответе демонстрирует, как получить имена файлов. Кроме того, просмотрите запрос в Fiddler (http://www.telerik.com/fiddler) или отладчик браузера и посмотрите, какой заголовок содержит имя файла, и извлеките его из объекта запроса HttpContext.Current. –

+0

Это код, который у меня есть сейчас, что заставляет меня писать на диск, прежде чем получить имя файла (насколько я могу судить). Я хочу получить имя без записи на диск. Кроме того, имя файла отсутствует в заголовке, оно находится в корпусе многочастной формы. Я не думаю, что у меня есть прямой доступ к этому. – GJK

+0

Я не могу запустить это через отладчик на данный момент, но я не вижу, где он пишет на диск, если только сервер не делает это за кулисами или до того, как будет выполнен ваш метод 'PostData(). (Я, вероятно, просто что-то пропустил.) –

ответ

1

Вы можете использовать MultipartMemoryStreamProvider, например:

 var provider = new MultipartMemoryStreamProvider(); 
     var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith(t => 
     { 
      var file = provider.Contents.First(); 
      var fileContents = await file.ReadAsByteArrayAsync(); 
      var filename = file.Headers.ContentDisposition.FileName.Replace("\"", string.Empty); 

      /// do other stuff 

      return Request.CreateResponse(HttpStatusCode.OK); 
     }); 

В этом случае содержание читается как массив байтов, но то же самое относится к потокам.

+0

Спасибо, это именно то, что мне нужно. Я смотрел на разных провайдеров, но по какой-то причине я не встречал поставщика памяти. – GJK

+0

Рад помочь :) –

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