بررسی روش آپلود فایلها در ASP.NET Core
نویسنده: وحید نصیری
تاریخ: ۱۳۹۵/۰۹/۱۸ ۱۰:۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
<form method="post" asp-action="Index" asp-controller="TestFileUpload" enctype="multipart/form-data"> <input type="file" name="files" multiple /> <input type="submit" value="Upload" /> </form>
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Index(IList<IFormFile> files)
public class TestFileUploadController : Controller
{
private readonly IHostingEnvironment _environment;
public TestFileUploadController(IHostingEnvironment environment)
{
_environment = environment;
} [HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(IList<IFormFile> files)
{
var uploadsRootFolder = Path.Combine(_environment.WebRootPath, "uploads");
if (!Directory.Exists(uploadsRootFolder))
{
Directory.CreateDirectory(uploadsRootFolder);
}
foreach (var file in files)
{
if (file == null || file.Length == 0)
{
continue;
}
var filePath = Path.Combine(uploadsRootFolder, file.FileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(fileStream).ConfigureAwait(false);
}
}
return View();
} public class UserViewModel
{
[Required(ErrorMessage = "Please select a file.")]
[DataType(DataType.Upload)]
public IFormFile Photo { get; set; }
} @model UserViewModel <form method="post" asp-action="UploadPhoto" asp-controller="TestFileUpload" enctype="multipart/form-data"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <input asp-for="Photo" /> <span asp-validation-for="Photo" class="text-danger"></span> <input type="submit" value="Upload"/> </form>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UploadPhoto(UserViewModel userViewModel)
{
if (ModelState.IsValid)
{
var formFile = userViewModel.Photo;
if (formFile == null || formFile.Length == 0)
{
ModelState.AddModelError("", "Uploaded file is empty or null.");
return View(viewName: "Index");
}
var uploadsRootFolder = Path.Combine(_environment.WebRootPath, "uploads");
if (!Directory.Exists(uploadsRootFolder))
{
Directory.CreateDirectory(uploadsRootFolder);
}
var filePath = Path.Combine(uploadsRootFolder, formFile.FileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(fileStream).ConfigureAwait(false);
}
RedirectToAction("Index");
}
return View(viewName: "Index");
} [FileExtensions(Extensions = ".png,.jpg,.jpeg,.gif", ErrorMessage = "Please upload an image file.")]
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class UploadFileExtensionsAttribute : ValidationAttribute
{
private readonly IList<string> _allowedExtensions;
public UploadFileExtensionsAttribute(string fileExtensions)
{
_allowedExtensions = fileExtensions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
public override bool IsValid(object value)
{
var file = value as IFormFile;
if (file != null)
{
return isValidFile(file);
}
var files = value as IList<IFormFile>;
if (files == null)
{
return false;
}
foreach (var postedFile in files)
{
if (!isValidFile(postedFile)) return false;
}
return true;
}
private bool isValidFile(IFormFile file)
{
if (file == null || file.Length == 0)
{
return false;
}
var fileExtension = Path.GetExtension(file.FileName);
return !string.IsNullOrWhiteSpace(fileExtension) &&
_allowedExtensions.Any(ext => fileExtension.Equals(ext, StringComparison.OrdinalIgnoreCase));
}
} public class UserViewModel
{
[Required(ErrorMessage = "Please select a file.")]
//`FileExtensions` needs to be applied to a string property. It doesn't work on IFormFile properties, and definitely not on IEnumerable<IFormFile> properties.
//[FileExtensions(Extensions = ".png,.jpg,.jpeg,.gif", ErrorMessage = "Please upload an image file.")]
[UploadFileExtensions(".png,.jpg,.jpeg,.gif", ErrorMessage = "Please upload an image file.")]
[DataType(DataType.Upload)]
public IFormFile Photo { get; set; }
} public class Model
{
public string Photo { get; set; }
} public class viewModel
{
public IFormFile Photo { get; set; }
} PM> Install-Package DNTCommon.Web.Core
Task < bool > SavePostedFileAsync ( IFormFile formFile , string destinationDirectoryName , bool allowOverwrite );
<?xml version="1.0" encoding="utf-8"?> <configuration> <!-- To customize the asp.net core module uncomment and edit the following section. For more info see https://go.microsoft.com/fwlink/?linkid=838655 --> <system.webServer> <handlers> <remove name="aspNetCore"/> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/> </handlers> <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" /> <security> <requestFiltering> <!-- This will handle requests up to 50MB --> <requestLimits maxAllowedContentLength="52428800" /> </requestFiltering> </security> </system.webServer> </configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<aspNetCore requestTimeout="00:20:00" .... />
</system.webServer>
</configuration> public void ConfigureServices(IServiceCollection services)
{
services.Configure<IISServerOptions>(options =>
{
options.MaxRequestBodySize = int.MaxValue;
});
services.Configure<FormOptions>(options =>
{
options.ValueLengthLimit = int.MaxValue;
options.MultipartBodyLengthLimit = long.MaxValue; // <-- ! long.MaxValue
options.MultipartBoundaryLengthLimit = int.MaxValue;
options.MultipartHeadersCountLimit = int.MaxValue;
options.MultipartHeadersLengthLimit = int.MaxValue;
}); [HttpPost] [RequestSizeLimit(40000000)] public async Task<IActionResult> UploadFiles(IFormFile file)
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseStartup<Startup>()
.ConfigureKestrel(kestrelServerOptions =>
{
kestrelServerOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10);
kestrelServerOptions.Limits.MaxRequestBodySize = 52428800; //50MB
});
}); public static async Task<ResponsePayload<string>> SaveBase64(this string imgBase64, string filePath, FileSizeType fileSizeType)
{
if (string.IsNullOrWhiteSpace(imgBase64))
return new ResponsePayload<string>(false, "فایل را وارد کنید.", null);
string data;
if (imgBase64.StartsWith("data:"))
{
string[] base64Arr = imgBase64.Split(',');
if (base64Arr.Length == 0)
return new ResponsePayload<string>(false, "فایل را وارد کنید.", null);
data = base64Arr[1];
}
else
{
data = imgBase64;
}
byte[] bytes = Convert.FromBase64String(data);
var fileType = GetFileExtension(imgBase64);
if (string.IsNullOrEmpty(fileType))
return new ResponsePayload<string>(false, "فایل وارد شده صحیح نمیباشد.", null);
using var stream = new MemoryStream(bytes);
IFormFile file = new FormFile(stream, 0, bytes.Length, filePath, "." + fileType);
string fileName = Guid.NewGuid().ToString().Replace("-", "");
return await UploadFile(file, filePath + fileName, fileSizeType);
}
private static string GetFileExtension(string base64String)
{
string data;
if (base64String.StartsWith("data:"))
{
string[] base64Arr = base64String.Split(',');
if (base64Arr.Length == 0)
return "";
data = base64Arr[1];
}
else
{
data = base64String;
}
return data.Substring(0, 5).ToUpper() switch
{
"IVBOR" => "png",
"/9J/4" => "jpg",
"AAAAF" => "mp4",
"JVBER" => "pdf",
"AAABA" => "ico",
"UMFYI" => "rar",
"E1XYD" => "rtf",
"U1PKC" => "txt",
"MQOWM" => "srt",
"77U/M" => "srt",
"UESDB" => "",
"" => "docx",
_ => string.Empty,
};
}
}
public class FileSizeType
{
public int Size { get; set; }
} private async Task UploadFiles(InputFileChangeEventArgs e)
{
foreach (var file in e.GetMultipleFiles())
{
var fileData = new FileToBeSaveVM();
var buffers = new byte[file.Size];
await file.OpenReadStream().ReadAsync(buffers);
fileData.FileName = file.Name;
fileData.FileSize = file.Size;
fileData.FileType = file.ContentType;
fileData.Extension = Path.GetExtension(file.Name);
fileData.ImageBytes = buffers;
lstFileToBeSaves.fileToBeSaves.Add(fileData);
}
}
public class FileToBeSaveVM
{
public byte[] ImageBytes { get; set; }
public string FileName { get; set; }
public string FileType { get; set; }
public string Extension { get; set; }
public long FileSize { get; set; }
} public async Task UploadFileAsync(List<FileToBeSaveVM> files, string uploadFolder)
{
var folderDirectory=createUploadDir(uploadFolder);
foreach (var file in files)
{
string fileExtenstion = Path.GetExtension(file.FileName);
string fileuniqName =$"{Guid.NewGuid()}{fileExtenstion}";
string fileName = Path.Combine(folderDirectory, fileuniqName);
string url=$"{uploadFolder}/{fileuniqName}";
using (var fileStream = File.Create(fileName))
{
await fileStream.WriteAsync(file.ImageBytes);
}
} Right click on the folder -> Properties -> Security tab -> Click at Edit button -> Enter `IIS AppPool\DefaultAppPool` user (IIS AppPool\<app_pool_name>) -> Click at Check names -> OK -> Then give it `write` or other permissions.
public async Task<IActionResult> FileUpload(IFormFile file)
{
if (file == null || file.Length == 0)
{
return BadRequest();
}
using (var memoryStream = new MemoryStream())
{
await file.CopyToAsync(memoryStream);
var fileBytes = memoryStream.ToArray();
// ... save it
}
} public async Task<IActionResult> FileUpload(IFormFile file)
{
if (file == null || file.Length == 0)
{
return BadRequest();
}
using (var memoryStream = new MemoryStream())
{
await file.CopyToAsync(memoryStream);
using (var img = Image.FromStream(memoryStream))
{
// TODO: ResizeImage(img, 100, 100);
}
}
}
بعد از اینکار، مسیر اشتراکی شبکهی داخلی (که دسترسی کاربر وارد شدهی به سیستم و شبکه، پیشتر به آن تنظیم شده)، به صورت یک درایو جدید، کنار سایر درایوهای قابل انتخاب توسط open file dialog استاندارد، ظاهر شده و قابل انتخاب میشود.
Path.Combine(_environment.WebRootPath, "uploads");
<form method="post" asp-action="UploadFiles" asp-controller="Home" enctype="multipart/form-data">
<input type="file" name="files" webkitdirectory />
<input type="submit" value="Upload" />
</form> using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace UploadFolderASPNETCore.Controllers
{
public class HomeController : Controller
{
private readonly IWebHostEnvironment _environment;
private const int MaxBufferSize = 0x10000;
public HomeController(IWebHostEnvironment environment)
{
_environment = environment;
}
public IActionResult Index()
{
return View();
}
[HttpPost("[action]")]
public async Task<IActionResult> UploadFiles(IList<IFormFile> files)
{
var uploadsRootFolder = Path.Combine(_environment.WebRootPath, "uploads");
CreateDir(uploadsRootFolder);
foreach (var file in files)
{
var dirPath = Path.GetDirectoryName(file.FileName);
CreateDir(Path.Combine(uploadsRootFolder, dirPath));
var filePath = Path.Combine(uploadsRootFolder, file.FileName);
using (var fileStream = new FileStream(filePath, FileMode.Create,
FileAccess.Write,
FileShare.None,
MaxBufferSize,
useAsync: true
))
{
await file.CopyToAsync(fileStream);
}
}
return RedirectToAction("Index");
}
private void CreateDir(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
}
}