نقل قول:
مثل تمام جوامع اینترنتی افراد تازه وارد جایگاه بسیار پائینی دارند .
نه دوست گرامی ، کمی زود قضاوت کردید.
من نمی دونستم که تاپیک قبلی رو مطالعه کردید. به نظر من در اون تاپیک خوب صحبت شده و من واقعا نمی دونم مشکل شما کجاست؟ اما برای اینکه بهتون ثابت کنم اشتباه تصور می کردید یک باره دیگه مجددا به طور گام به گام توضیح می دم:
سناریو: ما یکسری فایل داریم که هر کدوم یکسری Id دارن که توی دیتابیس ذخیره شدن. ما اونها رو با کدشون و extension ی aspx (علتش رو توضیح می دم) توی فولدر secureFiles ذخیره کردیم. در ضمن توی دیتابیس هم مشخص شده که چه کسانی به چه فایل هایی دسترسی دارند. حالا می خواهیم در یک محیط امن عملیات انتقال فایل رو انجام بدیم.
solution:
* نکته:
- تابع Authenticate رو هر جا دیدید این کار رو انجام می ده که توی دیتابیس نگاه میکنه که ببینه user ما به فایل دسترسی داره یا خیر اگر داشت true و در غیر این صورت false بر میگردونه
- تابع GiveMeFileName هم کد فایل رو میگیره و نام اون رو بر میگردنه
1. یک HttpHandler بوجود بیارید. برای اینکه با مشکل مواجه نشید روی یک فولدر خاص این کار رو انجام بدید:
<httpHandlers>
<add verb="*" path="SecureFiles/*.*" type="SecureDownload.DownloadHandler,SecureDownloa d" />
</httpHandlers>
کد بالا باعث میشه تمام درخواست های فایلهایی که asp.net می تونه اونها رو هندل کنه توسط کلاس DownloadHandler هندل بشن. (تمامی extension ها توسط asp.net هندل نمیشن مثلا html ، zip و ... پس باید از طریق IIS اونها رو به لیست extension هایی که asp.net اونها رو هندل میکنه اضافه کنید. اما در این مثال فرض می کنیم که به IIS دسترسی نداریم و هر جا بخواهیم از Handler استفاده کنیم از extension ی aspx استفاده میکنیم)
2. حالا یک کلاس می نویسیم تا بتونه عملیات download ما رو هندل کنه. برای این منظور باید اینترفیس IHttpHandler رو از Implement ، system.web کنید. این اینترفیس یک property ی readonly به نام IsReusable داره که طوری تنظیمش کنید که همیشه True برگردونه و یک متد ProcessRequest داره که یک پارامتر به نام context می گیره از نوع httpcontext که شما اون رو هم مثل object ی page در صفحات aspx تصور کنید.
Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
Dim fileID As String = context.Request.QueryString("fid")
'if user have access we'll give him the requested file
If Authenticate(GiveMeFileName(fileID), context.User.Identity.Name) Then
With context
.Response.Buffer = True
.Response.Clear()
.Response.AddHeader("content-disposition", "attachement; filename=" + GiveMeFileName(fileID))
.Response.WriteFile(fileID & ".aspx")
End With
Else
'otherwise give him a message
context.Response.Write("<font color=red>Access Deny!")
End If
End Sub
در کد بالا تنها چیزی که مفهوم نیست 2 تا مساله است:
اول: در خط Response.AddHeader ... کاری می کنیم که نام فایل درست در اختیار کاربر قرار بگیره
دوم: در خط Response.WriteFile ... فایل فیزیکی رو برای کاربر می فرستیم
3. در آخرین مرحله کافیه که هر وقت خواستید فایلی رو به کاربر بدید با استفاده از کد اون فایل و به صورت مثلا SecureFiles/get.aspx?fid=X که X هم کد فایل هست ، اون فایل رو به کاربر بدید.
اینم نمونه پروژه: