I've had a few requests to get the FlickrNet API Library working in Medium Trust mode under ASP.Net, so I thought I'd look at it. Here lies the tales and tribulations that such a journey took.
What is 'Medium Trust'?
Good darn question. I wasn't actually sure until I looked it up. Basically its a more secure environment for ASP.Net, often in which you might find yourself if using ASP.Net hosting on a shared server. It means you can't iterate through all the directories on the server and read a load of files, and it also has other restrictions, which I'll get to in a bit. (Read this for more details on the permission levels for each type of built in trust level.)
Where To Start
First thing is first, put a test web site into 'Medium Trust' mode.
Add the line to your system.web of either your applications web.config (for testing) or your machine.config.
<trust level="Medium" />
Easy so far.
The only thing is this just gave me a generic "SystemException: Security error" which was no help whatsoever.
Turns out that if I took OUT the [assembly:AssemblyKeyFile()] attribute from the AssemblyInfo.cs file it got rid of the above error, and gave me another one. But at least this new one has a line number associated with it! I still haven't managed to find a reason for this, but for now the FlickrNet assembly isn't signed. I shall probably have to start distributing a signed and a none signed version if I can't find an answer to this one.
(Update: Found out what the problem was here. When in Medium Trust mode the web application is considered a 'partial trust' application and by default code libraries do not allow partial trust applications to call them. I've added the AllowPartialTrustCallersAttribute() to the assembly and this is now working correctly. Hurray. See here for blog post)
File IO Errors
The main effect that Medium Trust has is on file access. You are not allowed to browse directory or create files outside of your own virtual web directory. Therefore I was obviously going to have to look in further detail at the caching infrastructure, specifically where it created these files.
I made all these changes (eventually), as well as adding the ability to specify the cache location from within the configuration file (and then added the ability to specify it at runtime as well, which took a bit more work).
I didn't have any unmanaged code in the API, or so I thought. Then I came across a bit of code which called the Marshal.GetHRForException method. This converts a .Net Exception into a HRESULT integer, i.e. an old school Win32 error code. The code in question was used to distinguish a file locked error from other types of IOExceptions. And hopefully unsuprisingly (from the description I've just given you) you should be able to tell that this method is effectively a call out to unmanaged code. I've yet to work out a replacement for this code so at the moment its commented out.
Other various things I had to work around was access to System.Net.WebProxy.GetDefaultProxy() static method, which throws an exception if called in Medium Trust. So I wrapped a try catch around this to catch that error. Then it turned out you cannot assign "null" to a HttpWebRequest.Proxy property if you are running in Medium Trust as well. Strange I though, but thats fine too (who wants to assign null to it anytime!)
The Final Stumbling Block - Shot in the Head?
Finally, everything compiled and I could create an actual Flickr class instance successfully. Then came the time to perform a quick test to Flickr.
Bam - turns out that any WebRequest to any web site (apart from the local web server) is blocked under Medium Trust. What? How is anyone ever going to use the FlickrNet API library under these scenarioes.
There is a Code Access Security document that is included with DotnetNuke that says the following code in your web.config will fix this particular problems:
<trust level=" " originUrl="http://www.flickr.com/*" />
The document also details ways to create a custom medium trust level. So if you are working in a modified medium trust envorinment you probably wont have this problem. You'll either have to ask your hosting provider or just play around to see what works.
As an aside, if working in the above Medium environment then picture downloading will not work, as pictures are hosted at http://static.flickr.com and not http://www.flickr.com. But then it you're working on a web app you probably just want to output the URL to the web page for the user's browser to download anyway.
It has been a fun run around the .Net Framework for this one little feature, so I hope you all appreciate the work :)
[tags]microsoft, security, asp.net, .net, web, flickrapi[/tags]