With the culture of knowledge sharing and open source spreading, everyone races to show they have something valuable that you may want. And while you may not ask for money for your content you may still want to get something in return, say a contact, an email address that?s verified (or not), to keep in touch with the consumer of your content.

Yet a full fledged registration doesn?t seem like a proper thing to do ? cluttering your EPiServer user repository with (let?s face it ? for a large part fake or temporary email addresses that user create only to get your content).

While there may be a lot of ways to handle that (streaming it through a page Response.WriteFile might seem as one of the more obvious ones), I would like to show you a cleaner, simpler and more elegant way that I?ve come up with.

We really don?t want people to deep link to our files without them knowing the files are from our site, that?s just rude ? so hiding them behind an obscure URL wouldn?t work (thus we cannot use the regular file providers). We?ve already establish that we don?t want to log them in, so setting file rights are useless. But I want all the benefits including client-side caching.

Basically the solution boils down to creating a thin layer over the File provider of our choice, in my case the versioning file provider. The only method we need to override in it is GetFile. I want to allow downloading for logged in users and I want to allow downloading for all users that have a ?magic-cookie? set. If either of the conditions are met, the file just downloads using the underlying provider?s routines including all the logic EPiServer has put for caching and rights. But if neither of the requirements are met, the user is directed to a page of our choice.

public override VirtualFile GetFile(string virtualPath) { string handledPath; if (TryGetHandledAbsolutePath(virtualPath, out handledPath)) { if ((HttpContext.Current.Profile != null && !HttpContext.Current.Profile.IsAnonymous) || HttpContext.Current.Request.Cookies.AllKeys.Contains(PASS_COOKIE_NAME)) { return base.GetFile(virtualPath); } HttpContext.Current.Response.Redirect( string.Format(registrationFormUrl,HttpContext.Current.Server.HtmlEncode(virtualPath))); return null; } return Previous.GetFile(virtualPath); }

How you specify that page?s totally up to you, but there is a nice initialization routine called during the Virtual Path Provider loading phase where all of the settings that are specified in your relevant web.config VPP declaration are passed to you, why not use it? What you?ll need define your VPP in the web.config is what follows:

<add showInFileManager="true" virtualName="CookieEnabled" virtualPath="~/CookieEnabled/" bypassAccessCheck="false" name="CookieEnabled" type="Cognifide.EPiServer.CookieEnabledVirtualPathProvider.CookieEnabledVirtualPathProvider,Cognifide.EPiServer.CookieEnabledVirtualPathProvider" indexingServiceCatalog="Web" physicalPath="C:\vpp\Resources" RegistrationFormUrl="/File-Asset-Request-Form/?filepath={0}" />

you can then define your class as:

public class CookieEnabledVirtualPathProvider : VirtualPathVersioningProvider { private const string REGISTRATION_FORM_URL_WEB_CONFIG_PARAM_NAME = "RegistrationFormUrl"; public const string PASS_COOKIE_NAME = "ResourcePass"; private string registrationFormUrl; public CookieEnabledVirtualPathProvider(string name, NameValueCollection configParameters) : base(name, configParameters) { registrationFormUrl = configParameters[REGISTRATION_FORM_URL_WEB_CONFIG_PARAM_NAME]; } ... }

So we know now where we want to direct people without a ?magic-cookie? who want to get our assets, and how to do it, but how do we finally allow that file to get down to them?

In your page ? for the same of simplicity I assume you will be using XForms for gathering the user data, but that really does not matter. When you validate the form data (or get the user to click on a link that you?ve sent them) you just set the ?magic? cookie that I called ?ResourcePass? to any value and to to expire in some a long amount of time, like a year. So that they can now access your files unrestrained and direct them BACK at the URL they came from ? and now the VPP will allow them to just download the file they initially requested:

protected void XForm_BeforeSubmitPostedData(object sender, SaveFormDataEventArgs e) { if (!Page.IsValid) { e.CancelSubmit = true; } else { string requestedFile = Request.Params["filepath"]; HttpCookie cookie = new HttpCookie(CookieEnabledVirtualPathProvider.PASS_COOKIE_NAME, "true"); cookie.Expires = DateTime.Now.AddYears(1); cookie.HttpOnly = true; Response.Cookies.Add(cookie); if (!string.IsNullOrEmpty(requestedFile)) { Response.Redirect(requestedFile); } } }
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 4.00 out of 5)

This entry (Permalink) was posted on Thursday, March 12th, 2009 at 10:01 pm and is filed under .Net Framework, ASP.NET, C#, EPiCode, EPiServer, Open Source, Software, Software Development, Solution, Web applications. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response , or trackback from your own site.