2015-12-16 8 views
1

Мы используем MultipartFormDataStreamProvider, чтобы сохранить загрузку файлов клиентами. У меня жесткое требование о том, что размер файла должен быть больше 1 КБ. Проще всего было бы, конечно, сохранить файл на диск, а затем посмотреть на файл, к сожалению, я не могу этого сделать. После того, как я сохраню файл на диск, у меня нет возможности доступа к нему, поэтому мне нужно посмотреть файл до его сохранения на диск. Я искал свойства провайдера потока, чтобы попытаться выяснить, какой размер файла, но, к сожалению, я не увенчался успехом.Определение размера файла с помощью MultipartFormDataStreamProvider перед сохранением файла?

Тестовый файл, который я использую, составляет 1025 байт.

MultipartFormDataStreamProvider.BufferSize 4096
Headers.ContentDisposition.Size является нулевым
ContentLength является нулевым

Есть ли способ определить размер файла, прежде чем они сохраняются в файловой системе?

ответ

1

Вы также можете прочитать содержимое запроса без использования MultipartFormDataStreamProvider. В этом случае все содержимое запроса (включая файлы) будет в памяти. Я привел пример того, как это сделать в this link.

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

2

Благодаря Guanxi я смог сформулировать решение. Я использовал свой код в ссылке в качестве основы, я просто добавил немного больше асинхронных/ожидающих доброты :). Я хотел бы добавить решение на всякий случай, если это помогает кому-либо еще:

private async Task SaveMultipartStreamToDisk(Guid guid, string fullPath) 
    { 
     var user = HttpContext.Current.User.Identity.Name; 

     var multipartMemoryStreamProvider = await Request.Content.ReadAsMultipartAsync(); 

     foreach (var content in multipartMemoryStreamProvider.Contents) 
     { 
      using (content) 
      { 
       if (content.Headers.ContentDisposition.FileName != null) 
       { 
        var existingFileName = content.Headers.ContentDisposition.FileName.Replace("\"", string.Empty); 

        Log.Information("Original File name was {OriginalFileName}: {guid} {user}", existingFileName, guid,user); 

        using (var st = await content.ReadAsStreamAsync()) 
        { 
         var ext = Path.GetExtension(existingFileName.Replace("\"", string.Empty)); 
         List<string> validExtensions = new List<string>() { ".pdf", ".jpg", ".jpeg", ".png" }; 
         //1024 = 1KB 
         if (st.Length > 1024 && validExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase)) 
         { 
          var newFileName = guid + ext; 
          using (var fs = new FileStream(Path.Combine(fullPath, newFileName), FileMode.Create)) 
          { 
           await st.CopyToAsync(fs); 
           Log.Information("Completed writing {file}: {guid} {user}", Path.Combine(fullPath, newFileName), guid, HttpContext.Current.User.Identity.Name); 
          } 
         } 
         else 
         { 
          if (st.Length < 1025) 
          { 
           Log.Warning("File of length {FileLength} bytes was attempted to be uploaded: {guid} {user}",st.Length,guid,user); 
          } 
          else 
          { 
           Log.Warning("A file of type {FileType} was attempted to be uploaded: {guid} {user}", ext, guid,user); 
          } 
          var responseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest) 
          { 
           Content = 
            st.Length < 1025 
             ? new StringContent(
              $"file of length {st.Length} does not meet our minumim file size requirements") 
             : new StringContent($"a file extension of {ext} is not an acceptable type") 
          }; 
          throw new HttpResponseException(responseMessage); 
         } 
        } 
       } 
      } 
     } 
+0

У меня ошибка System.ObjectDisposedException, когда я хочу получить длину. В чем проблема? –

+0

@SaraN похоже, что вы пытаетесь проверить длину после того, как объект был удален (st). Проверьте свой оператор 'using', чтобы убедиться, что вы не располагали объект до проверки его длины. Неуместная фигурная скобка могла определенно вызвать ее. У нас был код в производстве, так как я написал его, и у нас не было таких проблем. – coding4fun

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