在保存文件之前使用 MultipartFormDataStreamProvider 检测文件大小?
Detecting file size with MultipartFormDataStreamProvider before file is saved?
我们正在使用 MultipartFormDataStreamProvider
来保存客户端上传的文件。我有一个硬性要求,即文件大小必须大于 1KB。最简单的做法当然是将文件保存到磁盘,然后不幸地查看文件,我不能这样做。将文件保存到磁盘后,我无法访问它,因此我需要在将文件保存到磁盘之前查看它。我一直在查看流提供程序的属性,试图找出文件的大小,但不幸的是我一直没有成功。
我使用的测试文件是 1025 字节。
MultipartFormDataStreamProvider.BufferSize is 4096
Headers.ContentDisposition.Size is null
ContentLength is null
有没有办法在将文件保存到文件系统之前确定文件大小?
不使用MultipartFormDataStreamProvider
也可以读取请求内容。在那种情况下,所有请求内容(包括文件)都将在内存中。我已经在 this link 给出了一个如何做到这一点的例子。
在这种情况下,您可以读取 header 文件大小或读取流并检查文件大小。如果它满足你的标准,那么只把它写到想要的位置。
多亏了 Guanxi,我才得以制定解决方案。我在 link 中使用了他的代码作为基础,我只是添加了一点 async/await 优点:)。我想添加解决方案以防它对其他人有帮助:
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);
}
}
}
}
}
我们正在使用 MultipartFormDataStreamProvider
来保存客户端上传的文件。我有一个硬性要求,即文件大小必须大于 1KB。最简单的做法当然是将文件保存到磁盘,然后不幸地查看文件,我不能这样做。将文件保存到磁盘后,我无法访问它,因此我需要在将文件保存到磁盘之前查看它。我一直在查看流提供程序的属性,试图找出文件的大小,但不幸的是我一直没有成功。
我使用的测试文件是 1025 字节。
MultipartFormDataStreamProvider.BufferSize is 4096
Headers.ContentDisposition.Size is null
ContentLength is null
有没有办法在将文件保存到文件系统之前确定文件大小?
不使用MultipartFormDataStreamProvider
也可以读取请求内容。在那种情况下,所有请求内容(包括文件)都将在内存中。我已经在 this link 给出了一个如何做到这一点的例子。
在这种情况下,您可以读取 header 文件大小或读取流并检查文件大小。如果它满足你的标准,那么只把它写到想要的位置。
多亏了 Guanxi,我才得以制定解决方案。我在 link 中使用了他的代码作为基础,我只是添加了一点 async/await 优点:)。我想添加解决方案以防它对其他人有帮助:
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);
}
}
}
}
}