آموزش ایجاد لینک دانلود موقت در MVC 5
آموزش ایجاد لینک دانلود موقت در MVC 5
در این پست قصد داریم تا نحوه ایجاد لینک دانلود موقت در Asp.Net MVC 5 را آموزش دهیم.
در آموزش های قبلی نحوه ایجاد لینک دانلود موقت در Asp.Net را توضیح دادیم.
برای ایجاد لینک دانلود موقت در Asp.Net MVC 5 ابتدا یک جدول با فلید های زیر در دیتابیس ایجاد کنید.
نکته:
ما در Asp.Net MVC 5 به جای ایجاد دیتابیس در Sql Server از طریق Model اقدام به ایجاد خودکار دیتابیس می کنیم.
TemporaryDownloadId : آی دی جدول که به صورت خودکار ایجاد می شود
DownloadTitle : عنوان لینک دانلود را ذخیره می کنیم
Url : یک فیلد از نوع رشته که آدرس واقعی لینک دانلود را ذخیره می کنیم
DownloadToken : یک فیلد از نوع رشته که کد دانلود را ذخیره می کنیم
ExpiryDate : یک فیلد از نوع تاریخ که تاریخ انقضاء دانلود را ذخیره می دارد
Hits : یک فیلد از نوع عددی که تعداد دفعات دانلود را ذخیره می کنیم
ExpireAfterDownload : یک فیلد از نوع Boolean که بعد از دانلود، لینک دانلود منقضی می شود
Downloaded : یک فیلد از نوع Boolean که فایل دانلود شده یا نه، را ذخیره می کنیم
نکته :
برای امنیت بیشتر همچنین می توانید آی دی کاربر را نیز ذخیره کنید.
حال یک کنترلر به نام Home ایجاد می کنیم و سپس یک اکشن ریزالت به نام Index ایجاد می کنیم و سپس یک ویو برای آن ایجاد می کنیم و کدهای داخل ویو به صورت زیر می باشد.
اکشن ریزالت Index
public ActionResult Index() { return View(); }
ویو Index
@model SourceCodeMVC5.Models.DownloadLink @{ Layout = null; } <!DOCTYPE html> <html> <head> <link href="~/Content/bootstrap.min.css" rel="stylesheet" /> <meta name="viewport" content="width=device-width" /> <title>Index</title> <style type="text/css"> body { direction: rtl; background-color: #1e90ff; } </style> </head> <body> <div class="container"> <div class="row"> <div class="container"> <div class="form-horizontal"> <div class="alert alert-info text-center"> <h3>ایران گنج</h3> <p>ایجاد لینک دانلود موقت</p> </div> <div class="thumbnail"> @ViewBag.Message <br /> @Html.Raw(ViewBag.DownloadLinkShow) </div> @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.DownloadTitle, new { htmlAttributes = new { @class = "cotrol-label col-lg-2" } }) <div class="col-lg-12"> @Html.EditorFor(model => model.DownloadTitle, new { htmlAttributes = new { @class = "form-control " } }) @Html.ValidationMessageFor(model => model.DownloadTitle, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Url, new { htmlAttributes = new { @class = "cotrol-label col-lg-2" } }) <div class="col-lg-12"> @Html.EditorFor(model => model.Url, new { htmlAttributes = new { @class = "form-control " } }) @Html.ValidationMessageFor(model => model.Url, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.ExpireAfterDownload, new { htmlAttributes = new { @class = "cotrol-label col-lg-2" } }) <div class="checkbox col-lg-12"> @Html.EditorFor(model => model.ExpireAfterDownload, new { htmlAttributes = new { @class = "" } }) @Html.ValidationMessageFor(model => model.ExpireAfterDownload, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.ExpiryDate, new { htmlAttributes = new { @class = "cotrol-label col-lg-2" } }) <div class="col-lg-12"> @Html.EditorFor(model => model.ExpiryDate, new { htmlAttributes = new { @class = "form-control " } }) @Html.ValidationMessageFor(model => model.ExpiryDate, "", new { @class = "text-danger" }) </div> </div> <input type="submit" value="ثبت" class="btn btn-success" /> } </div> </div> </div> </div> <script src="~/Scripts/jquery-1.9.1.min.js"></script> <script src="~/Scripts/bootstrap.min.js"></script> </body> </html>
در کد های بالا یک فرم ایجاد کردیم تا بتوانیم اطلاعات لینک دانلود را در دیتابیس ذخیره کنیم.
نکته : هنگام ثبت لینک واقعی مسیر آن را به صورت زیر وارد کنید
Downloads/asp.zip/~
اکشن ریزالت Index مربوط به ثبت لینک دانلود.
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Index([Bind(Include = "TemporaryDownloadId,DownloadTitle,Url,DownloadToken,Hits,ExpireAfterDownload,Downloaded,ExpiryDate")] DownloadLink downloadLink) { if (ModelState.IsValid) { downloadLink.DownloadTitle = downloadLink.DownloadTitle.Trim(); downloadLink.DownloadToken = GetDownloadToken(10); downloadLink.Hits = 0; downloadLink.Downloaded = false; db.DownloadLinks.Add(downloadLink); db.SaveChanges(); ViewBag.Message = "لینک دانلود ثبت شد"; ViewBag.DownloadLinkShow = string.Format("<a href='/dl/{0}'>{1}</a>", downloadLink.DownloadToken, downloadLink.DownloadTitle); } return View(downloadLink); }
بعد از ثبت لینک دانلود توسط یک ViewBag لینک دانلود را به کاربر نمایش می دهیم.
در کلیک دکمه ثبت، اطلاعات لینک دانلود را در دیتابیس ذخیره می کنیم و همچنین با استفاده از متد GetDownloadToken یک کد 10 کارکتری تولید می کنیم.
نکته:
شما نیز می توانید به جای متد GetDownloadToken که یک کد 10 کارکتری تولید می کند از یک Guid نیز استفاده کنید که یک کد 32 کارکتری تولید می کند.
private string GetDownloadToken(int length) { int intZero = '0'; int intNine = '9'; int intA = 'A'; int intZ = 'Z'; int intCount = 0; int intRandomNumber = 0; string strDownloadToken = ""; Random objRandom = new Random(System.DateTime.Now.Millisecond); while (intCount < length) { intRandomNumber = objRandom.Next(intZero, intZ); if (((intRandomNumber >= intZero) && (intRandomNumber <= intNine) || (intRandomNumber >= intA) && (intRandomNumber <= intZ))) { strDownloadToken = strDownloadToken + (char)intRandomNumber; intCount++; } } return strDownloadToken; }
همچنین احتمال اینکه کد تولید شده تکراری باشد به همین دلیل دیتابیس را چک می کنیم که کد تولید شده تکراری نباشد. در صورتی تکراری بودن یک کد جدید تولید می کنیم.
زمانی که روی لینک موقت کلیک می کنید اکشن ریزالت Download اجرا می شود.
کدهای صفحه اکشن ریزالت Download به صورت زیر می باشد.
[Route("dl/{downloadtoken}")] [AllowAnonymous] public ActionResult Download(string downloadtoken) { if (downloadtoken == null) { return RedirectToAction("DownloadError"); } else { if (downloadtoken.Contains(".") || downloadtoken.ToLower().Contains(".zip") || downloadtoken.ToLower().Contains(".rar")) { return RedirectToAction("DownloadError"); } try { var data = from d in db.DownloadLinks where d.DownloadToken == downloadtoken select d; int count = data.Count(); if (count == 0) { return RedirectToAction("DownloadError"); } else { DownloadLink oDownloadLink = data.SingleOrDefault(); if (oDownloadLink.ExpireAfterDownload) { if (oDownloadLink.Downloaded) { return RedirectToAction("DownloadError"); } } else { if (oDownloadLink.ExpiryDate < DateTime.Now) { return RedirectToAction("DownloadError"); } } string strFormatFile = ""; if (oDownloadLink.Url.ToLower().Contains(".zip")) { strFormatFile = "zip"; } else { strFormatFile = "rar"; } string path = Server.MapPath(oDownloadLink.Url); FileStream fs = System.IO.File.OpenRead(path); byte[] fileData = new byte[fs.Length]; fs.Read(fileData, 0, (int)fs.Length); Response.Clear(); Response.AddHeader("Content-Type", "application/" + strFormatFile); Response.AddHeader("Content-Disposition", "inline;filename=" + Path.GetFileName(path)); Response.BinaryWrite(fileData); Response.Flush(); Response.Close(); if (oDownloadLink.ExpireAfterDownload) { oDownloadLink.Downloaded = true; oDownloadLink.Hits = oDownloadLink.Hits + 1; db.SaveChanges(); } } return View(); } catch (Exception ex) { string errors = ex.Message; return RedirectToAction("DownloadError"); } } }
ابتدا کد دانلود را از URL دریافت می کنیم و سپس در دیتابیس چک می کنیم که وجود دارد یا نه در صورت عدم وجود کد دانلود در دیتابیس کاربر را به اکشن ریزلت DownloadError هدایت می کنیم در این صفحه کد خاصی نوشته نشده و فقط پیغام لینک دانلود منقضی شده است را نمایش می دهیم.
در صورت وجود کد دانلود در دیتابیس، بررسی می کنیم ExpireAfterDownload در دیتابس true هست یا نه و سپس Downloaded در دیتابیس true است یا نه در صورت صحیح بودن دو شرط کاربر را به اکشن ریزلت DownloadError هدایت میکنیم پیغام لینک دانلود منقضی شده است را نیز نمایش می دهیم.
در صورت اجرا نشدن دو شرط قبلی بررسی می کنیم که تاریخ لینک دانلود به اتمام نرسیده باشد در صورت منقضی شدن تاریخ لینک دانلود کاربر را به اکشن ریزلت DownloadError هدایت می کنیم.
نکته:
توجه کنید که مسیر دسترسی به لینک دانلود به صورت Route تنظیم شده است
در اینجا نیز می توانید بر اساس تعداد دانلود نیز بررسی کنید.
سپس در متغییر path آدرس نسبی را به آدرس فیزیکی تبدیل می کنیم. و همچنین ما دو فرمت zip و rar را بررسی کردیم که شما می توانید فرمت های دیگر را نیز بررسی کنید.
و در نهایت در دیتابیس Downloaded را برابر true قرار می دهیم و همچنین به تعداد دانلود یکی اضافه می کنیم.
نظر / سوال