This morning I was upgrading my HtmlParser and YahooFinanceParser libraries to use .Net 4.0 frameowrk. isual Studio 2010 conversion wizard did all the job of conversion. When I launched my test application to make sure everything was working, I was hit by a surprise. No code was changed other than compilation target was changed to .Net 4.0 and I got the following exception.
MethodAccessException Attempt by method 'Winista.YahooFinanceParser.StockQuoteFetcher.GetStockQuote(System.String to access method 'Winista.YahooFinanceParser.StockQuoteFetcher.CreateRequestAttributes(System.String)' failed.
Since all assemblies were recompiled so the error details were not of much help asking to recompile with new referenced assmblies. I started with my usual ways of isolating the problem. Here was the call flow.
Console Application -->Library1 -->Library2
Exception was being thrown from a method in Library1. The exception message was not much of a help because it is complaining that class is having problem calling into its own private method. So I started my usual way of isolating the problem. The problem definitely seems to be code that was in CreateRequestAttributes. So I took the code out of there and directly put in the method GetStockQuote that was calling into CreateRequestAttributes. Now when i ran the test, i got the following exception.
MethodAccessException Attempt by security transparent method 'Winista.YahooFinanceParser.StockQuoteFetcher.TestIt(System.String)' to access security critical method 'Winista.Text.HtmlParser.Http.RequestAttributes..ctor()' failed. Assembly 'Winista.YahooFinanceParser, Version=188.8.131.52, Culture=neutral, PublicKeyToken=null' is marked with the AllowPartiallyTrustedCallersAttribute, and uses the level 2 security transparency model. Level 2 transparency causes all methods in AllowPartiallyTrustedCallers assemblies to become security transparent by default, which may be the cause of this exception.
Now this exception detail made more sense. So let me explain what this issue is. In .Net4.0 framework, security tranparency rules prevent any security transparent code to call into security critical code. In .Net4.0 default security transpareny of library assemblies is security critical. My assembly Winista.YahooFinanceParser is marked with AllowPartiallyTrustedCallers attributes. This explicitly tells the security framework that this library will accept calls from security transparent callers. But the assembly Winista.HtmlParserPro do not have AllowPartiallyTrustedCallers attribute on it. This means it will not allow partial trusted or untrusted code to call into it. Therefore when method from Winista.YahooFinanceParser tried to create an object from Winista.HtmlParser, it threw MethodAccessException.
My original intention was to allow partially trusted to call into all these assemblies. But somehow AllowPartiallyTrustedCallers attribute slipped through the cracks for one assembly. After I applied AllowPartiallyTrustedCallers on Winista.HtmlParserPro assemnly, everything worked fine.
So if you are upgrading your libraries to .Net4.0 and you are not restricting any partially trusted or security transparent code to call into it, then put AllowPartiallyTrustedCallers attribute on your assemblies.