اگر خروجی return File را در اکشن متدهای ASP.NET Core همانند ASP.NET MVC 5.x مورد استفاده قرار دهید و در آن مسیرکامل فایل را برای بازگشت قید کرده باشید، پیام یافت نشدن فایل را دریافت خواهید کرد؛ هرچند این فایل بر روی سرور و در مسیر ذکر شده وجود خارجی دارد. علت آنرا در تصویر ذیل میتوانید مشاهده کنید:
روشهای مختلف بازگشت فایلها به سمت کلاینت در ASP.NET Core
در ASP.NET Core، نوعهای کاملتری از Action Resultهای مرتبط با بازگشت فایلها تدارک دیده شدهاند که نحوهی طراحی آنها را در شکل فوق ملاحظه میکنید. در اینجا FileResult والد تمام حالتهای بازگشت فایل است که شامل موارد ذیل میشود:
FileContentResult: از آن برای بازگشت آرایهای از بایتها استفاده میشود:
زمانیکه Controller جاری از کلاس پایه Controller ارث بری میکند، متد File در این کلاس پایه قرار دارد. به همین جهت مانند مثال فوق به سادگی میتوان به آن، بدون ذکر new دسترسی یافت. روش دیگر دسترسی به FileContentResult به صورت ذیل است که معادل قطعه کد فوق میباشد:
FileStreamResult: این Action Result قابلیت Streaming بازگشت فایلها را مهیا میکند:
در اینجا برای مثال میتوان یک MemoryStream و یا یک FileStream را به سمت کاربر ارسال کرد. این روش نسبت به خواندن فایلها در آرایهای از بایتها و سپس ارسال یکجای آن، بهینهتر است و حافظهی کمتری را مصرف میکند.
اگر خواستیم مستقیما با FileStreamResult کار کنیم، روش کار به صورت ذیل است:
VirtualFileResult: در این مورد آدرسی را که ارائه میدهید، باید به فایلی درون پوشهی wwwroot اشاره کند (علت اصلی بروز مشکلی که در مقدمهی بحث عنوان شد). در اینجا آدرس کامل فایل مدنظر نیست.
و یا معادل همین قطعه کد با استفاده از VirtualFileResult اصلی به صورت ذیل است:
PhysicalFileResult: اگر قصد دارید آدرس کامل فایلی را مشخص کنید (بجای مسیر نسبی آن که از wwwroot شروع میشود؛ مانند حالت قبل)، اینبار باید از متد PhysicalFile استفاده کرد:
این قطعه کد نیز بر اساس استفادهی مستقیم از PhysicalFileResult شکل زیر را میتواند پیدا کند:
در این متدها و کلاسها، اگر FileDownloadName حاوی حروف اسکی نباشد، به صورت خودکار encoding از نوع RFC5987 بر روی آن اعمال خواهد شد.
روشهای مختلف بازگشت فایلها به سمت کلاینت در ASP.NET Core
در ASP.NET Core، نوعهای کاملتری از Action Resultهای مرتبط با بازگشت فایلها تدارک دیده شدهاند که نحوهی طراحی آنها را در شکل فوق ملاحظه میکنید. در اینجا FileResult والد تمام حالتهای بازگشت فایل است که شامل موارد ذیل میشود:
FileContentResult: از آن برای بازگشت آرایهای از بایتها استفاده میشود:
//returns the file content as an array of bytes public FileContentResult FileContentActionResult() { var file = System.IO.File.ReadAllBytes(@"C:\path\dir1\HomeController.cs"); return File(file, "text/plain", "HomeController.cs"); }
public IActionResult TestFileContentActionResult() { var file = System.IO.File.ReadAllBytes(@"C:\path\dir1\HomeController.cs"); return new FileContentResult(file, "text/plain") { FileDownloadName = "HomeController.cs" }; }
FileStreamResult: این Action Result قابلیت Streaming بازگشت فایلها را مهیا میکند:
//return the file as a stream public FileStreamResult FileStreamActionResult() { //var file = System.IO.File.ReadAllBytes(@"C:\path\dir1\HomeController.cs"); //var stream = new MemoryStream(file, writable:true); var fileStream = new FileStream(@"C:\path\dir1\HomeController.cs", FileMode.Open, FileAccess.Read); return File(fileStream, "text/plain", "HomeController.cs"); }
اگر خواستیم مستقیما با FileStreamResult کار کنیم، روش کار به صورت ذیل است:
public IActionResult TestFileStreamActionResult() { //var file = System.IO.File.ReadAllBytes(@"C:\path\dir1\HomeController.cs"); //var stream = new MemoryStream(file, writable:true); var fileStream = new FileStream(@"C:\path\dir1\HomeController.cs", FileMode.Open, FileAccess.Read); return new FileStreamResult(fileStream, "text/plain") { FileDownloadName = "HomeController.cs" }; }
VirtualFileResult: در این مورد آدرسی را که ارائه میدهید، باید به فایلی درون پوشهی wwwroot اشاره کند (علت اصلی بروز مشکلی که در مقدمهی بحث عنوان شد). در اینجا آدرس کامل فایل مدنظر نیست.
//returns a file specified with a virtual path public VirtualFileResult VirtualFileActionResult() { return File("/css/site.css", "text/plain", "site.css"); }
public IActionResult TestVirtualFileActionResult() { return new VirtualFileResult("/css/site.css", "text/plain") { FileDownloadName = "site.css" }; }
PhysicalFileResult: اگر قصد دارید آدرس کامل فایلی را مشخص کنید (بجای مسیر نسبی آن که از wwwroot شروع میشود؛ مانند حالت قبل)، اینبار باید از متد PhysicalFile استفاده کرد:
//returns the specified file on disk, that is it's physical address public PhysicalFileResult PhysicalFileActionResult() { return PhysicalFile(@"C:\path\dir1\HomeController.cs", "text/plain", "HomeController.cs"); }
public IActionResult TestPhysicalFileActionResult() { return new PhysicalFileResult(@"C:\path\dir1\HomeController.cs", "text/plain") { FileDownloadName = "HomeController.cs" }; }
در این متدها و کلاسها، اگر FileDownloadName حاوی حروف اسکی نباشد، به صورت خودکار encoding از نوع RFC5987 بر روی آن اعمال خواهد شد.