نحوه ایجاد لینک دانلود موقت در Asp.Net
نحوه ایجاد لینک دانلود موقت در Asp.Net
در این پست قصد داریم تا به طور کامل نحوه ایجاد لینک موقت در Asp.Net را آموزش دهیم.
در این آموزش جهت کار با دیتابیس از Entity Framework استفاده شده و از این به بعد جهت بهبود کیفیت آموزش ها از Entity Framework استفاده خواهیم کرد و شما همچنین می توانید از ADO.Net نیز استفاده کنید.
چرا باید لینک های دانلود را به صورت لینک موقت در بیاریم و همچنین دسترسی به لینک دانلود را برای کاربران خاص در نظر بگیریم؟ به دو دلیل
- کاربرانی که فایل رو خریداری کرده اند می توانند لینک دانلود را برای دوستانش ارسال کنند و آنها هم فایل را دانلود کنند. پس برای امینت بیشتر میتوانید فایل را برای هر کاربر لینک منحصر به فرد ایجاد کنید که مدت زمان داشته باشد و بعد از مدت مورد نظر دیگر اعتباری نداشته باشد.
- امنیت فایل دانلود به معتبر بودن کاربر ارتباط دارد که این فقط شامل کاربران لاگین نیست بلکه باید کاربر برای آن معتبر باشد. این کار بهتره با دیتابیس صورت گیرد.
ابتدا یک دیتابیس با یک جدول با فلید های زیر در ایجاد کنید.
TemporaryDownloadId : آی دی جدول که به صورت خودکار ایجاد می شود
DownloadTitle : عنوان لینک دانلود را ذخیره می کنیم
Url : یک فیلد از نوع رشته که آدرس واقعی لینک دانلود را ذخیره می کنیم
DownloadToken : یک فیلد از نوع رشته که کد دانلود را ذخیره می کنیم
ExpiryDate : یک فیلد از نوع تاریخ که تاریخ انقضاء دانلود را ذخیره می دارد
Hits : یک فیلد از نوع عددی که تعداد دفعات دانلود را ذخیره می کنیم
ExpireAfterDownload : یک فیلد از نوع Boolean که بعد از دانلود، لینک دانلود منقضی می شود
Downloaded : یک فیلد از نوع Boolean که فایل دانلود شده یا نه را ذخیره می کنیم
نکته:
برای امنیت بیشتر همچنین می توانید آی دی کاربر را نیز ذخیره کنید.
حال یک صفحه به نام TemporaryUrlGenerator.aspx ایجاد می کنیم و کدهای آن به شکل زیر می باشد.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TemporaryUrlGenerator.aspx.cs" Inherits="TemporaryUrlGenerator" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <fieldset dir="rtl"> <legend>خطاهای اتفاق افتاده در سایت</legend> <div id="divPageMessage"> <asp:Literal ID="litPageMessage" runat="server"></asp:Literal> </div> <div> <div> <div> <label>عنوان دانلود<span class="required">*</span></label> </div> <div> <asp:TextBox ID="txtDownloadTitle" runat="server" MaxLength="100" ValidationGroup="Download" /> <asp:RequiredFieldValidator ID="rfvFullName" runat="server" ControlToValidate="txtDownloadTitle" Display="Dynamic" SetFocusOnError="True" EnableClientScript="True" ForeColor="red" Text="*" ValidationGroup="Download" /> </div> </div> <div> <div> <label>آدرس واقعی دانلود<span class="required">*</span></label> </div> <div> <asp:TextBox ID="TxtUrl" runat="server" MaxLength="100" ValidationGroup="Download" /> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TxtUrl" Display="Dynamic" SetFocusOnError="True" EnableClientScript="True" ForeColor="red" Text="*" ValidationGroup="Download" /> </div> </div> <div> <div> <label>انقضاء بعد از دانلود<span class="required">*</span></label> </div> <div> <asp:CheckBox ID="chkExpireAfterDownload" runat="server" MaxLength="100" ValidationGroup="Download" /> </div> </div> <div> <div> <label>تاریخ انقضا<span class="required">*</span></label> </div> <div> <asp:TextBox ID="txtExpiryDate" runat="server" MaxLength="100" ValidationGroup="Download" TextMode="Date" /> <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="txtExpiryDate" Display="Dynamic" SetFocusOnError="True" EnableClientScript="True" ForeColor="red" Text="*" ValidationGroup="Download" /> </div> </div> <br /> <div> <asp:Button ID="btnAdd" runat="server" Text="ثبت" ValidationGroup="Download" OnClick="btnAnswerToIdea_Click" CssClass="link-button green" /> <asp:HyperLink ID="hyperLinkDownload" runat="server"></asp:HyperLink> </div> </div> </fieldset> </form> </body> </html>
در کد های بالا یک فرم ایجاد کردیم تا بتوانیم اطلاعات لینک دانلود را در دیتابیس ذخیره کنیم. همچنین ما از یک HyperLink لینک نیز استفاده کردیم که بعد از ثبت اطلاعات در دیتابیس لینک موقتی که ایجاد شده را در این HyperLink نمایش دهیم.
نکته : هنگام ثبت لینک واقعی به صورت زیر وارد کنید
~/downloads/asp.zip
کدهای سی شارپ آن به شکل زیر میباشد.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using Models; public partial class TemporaryUrlGenerator : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void btnAnswerToIdea_Click(object sender, EventArgs e) { //ایجاد یک شی از دیتابیس کانتکست DataBaseContext oDataBaseContext = null; try { //نیو کرد شی دیتابیس کانتکست oDataBaseContext = new DataBaseContext(); TemporaryDownload oTemporaryDownload = null; oTemporaryDownload = new TemporaryDownload(); oTemporaryDownload.DownloadTitle = txtDownloadTitle.Text.Trim(); oTemporaryDownload.Url = TxtUrl.Text.Trim(); oTemporaryDownload.ExpiryDate = Convert.ToDateTime(txtExpiryDate.Text.ToString()); oTemporaryDownload.ExpireAfterDownload = chkExpireAfterDownload.Checked; oTemporaryDownload.DownloadToken = GetDownloadToken(10); oTemporaryDownload.Hits = 0; oTemporaryDownload.Downloaded = false; oDataBaseContext.TemporaryDownloads.Add(oTemporaryDownload); oDataBaseContext.SaveChanges(); litPageMessage.Text = "لینک دانلود ثبت شد"; hyperLinkDownload.NavigateUrl = string.Format("~/downloads/{0}", oTemporaryDownload.DownloadToken); hyperLinkDownload.Text = Page.ResolveClientUrl(hyperLinkDownload.NavigateUrl); } //در صورت بروز خطا آن را نمایش دهد catch (Exception ex) { litPageMessage.Text = ex.Message; } //در نهایت اگر دیتابیس کانتکست نال نبود نال می کنیم finally { if (oDataBaseContext != null) { oDataBaseContext.Dispose(); oDataBaseContext = null; } } } 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; } }
در کلیک دکمه ثبت، اطلاعات لینک دانلود را در دیتابیس ذخیره می کنیم و همچنین با استفاده از متد GetDownloadToken یک کد 10 کارکتری تولید می کنیم.
نکته:
شما نیز می توانید به جای متد GetDownloadToken که یک کد 10 کارکتری تولید می کند از یک Guid نیز استفاده کنید که یک کد 32 کارکتری تولید می کند.
همچنین احتمال اینکه کد تولید شده تکراری باشد به همین دلیل دیتابیس را چک می کنیم که کد تولید شده تکراری نباشد. در صورتی تکراری بودن یک کد جدید تولید می کنیم.
بعد از ثبت اطلاعات در دیتابیس لینک موقت ایجاده شده را در HyperLink لینک نمایش می دهیم.
زمانی که روی لینک موقت کلیک می کنید به صفحه DownloadFile.aspx می رود حال صفحه DownloadFile.aspx را ایجاد می کنیم.
کدهای صفحه DownloadFile.aspx به صورت زیر می باشد.
<%@ Page Language="C#" %> <%@ Import Namespace="System.IO" %> <%@ Import Namespace="Models" %> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { string downloadtoken = Page.RouteData.Values["downloadtoken"].ToString(); DataBaseContext oDataBaseContext = null; try { //نیو کرد شی دیتابیس کانتکست oDataBaseContext = new DataBaseContext(); var data = from d in oDataBaseContext.TemporaryDownloads where d.DownloadToken == downloadtoken select d; int count = data.Count(); if (count == 0) { Response.Redirect("~/DownloadError.aspx"); } else { TemporaryDownload oTemporaryDownload = data.SingleOrDefault(); if (oTemporaryDownload.ExpireAfterDownload) { if (oTemporaryDownload.Downloaded) { Response.Redirect("~/DownloadError.aspx"); } } else { if (oTemporaryDownload.ExpiryDate < DateTime.Now) { Response.Redirect("~/DownloadError.aspx"); } } string path = Server.MapPath(oTemporaryDownload.Url); string strFormatFile = ""; if (oTemporaryDownload.Url.ToLower().Contains(".zip")) { strFormatFile = "zip"; } else { strFormatFile = "rar"; } FileStream fs = 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 (oTemporaryDownload.ExpireAfterDownload) { oTemporaryDownload.Downloaded = true; oTemporaryDownload.Hits = oTemporaryDownload.Hits + 1; oDataBaseContext.SaveChanges(); } } } catch (Exception ex) { } //در نهایت اگر دیتابیس کانتکست نال نبود نال می کنیم finally { if (oDataBaseContext != null) { oDataBaseContext.Dispose(); oDataBaseContext = null; } } } </script>
ابتدا توسط دستور Page.RouteData.Values کد دانلود را از URL دریافت می کنیم و سپس در دیتابیس چک می کنیم که وجود دارد یا نه در صورت عدم وجود کد دانلود در دیتابیس کاربر را به صفحه DownloadError.aspx هدایت می کنیم در این صفحه کد خاصی نوشته نشده و فقط پیغام لینک دانلود منقضی شده است را نمایش می دهیم.
در صورت وجود کد دانلود در دیتابیس، بررسی می کنیم ExpireAfterDownload در دیتابس true هست یا نه و سپس Downloaded در دیتابیس true است یا نه در صورت صحیح بودن دو شرط کاربر را به صفحه DownloadError.aspx هدایت میکنیم پیغام لینک دانلود منقضی شده است را نمایش می دهیم.
در صورت اجرا نشدن دو شرط قبلی بررسی می کنیم که تاریخ لینک دانلود به اتمام نرسیده باشد در صورت منقضی شدن تاریخ لینک دانلود کاربر را به صفحه DownloadError.aspx هدایت می کنیم.
نکنه:
در اینجا نیز می توانید بر اساس تعداد دانلود نیز بررسی کنید.
سپس در متغییر path آدرس نسبی را به آدرس فیزیکی تبدیل می کنیم. و همچنین ما دو فرمت zip و rar را بررسی کردیم که شما می توانید فرمت های دیگر را نیز بررسی کنید.
و در نهایت در دیتابیس Downloaded را برابر true قرار می دهیم و همچنین به تعداد دانلود یکی اضافه می کنیم.
در آخر در فایل Global.asax نیز کد زیر را اضافه کنید.
void Application_Start(object sender, EventArgs e) { // Code that runs on application startup RouteTable.Routes.MapPageRoute("Downloads", "downloads/{downloadtoken}", "~/DownloadFile.aspx"); }
نظر / سوال