System.TypeLoadException: Inheritance security rules violated by type: 'System.Net.Http.Formatting.JsonContractResolver' - json.net

I'm getting a very annoying error about System.Net.Http.Formatting.JsonContractResolver having inheritance security rules violated in a project which uses PCLs.
Here is the setup and how I tracked down the problem.
Project 1 - Custom.WebApi (portable, targeting .net 4.5, Core 5.0, Win8, Xamarin.Android, Xamarin.iOS, Xamarin.iOS(Classic))
This project is an abstraction over HttpClient to unify the return types of Get, Post, Delete, ... and depends ONLY on Newtonsoft.Json and .NET with this profile.
We are using Newtsonsoft.Json pcl version 6.0.8.($packagesFolder\Newtonsoft.Json.6.0.8\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll)
Project 2 - Custom.WepApi.Tests (unit test project)
This is a test project for the WebApi project. It references full version of 6.0.8 ($packagesFolder\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll)
This project is able to run tests against WebApi project no problem.
Project 3 - MyWebsite (ASP.NET WebApi site)
This project is a WebApi project where the response types are unified and found in the Custom.WebApi project. This references a bunch of 3rd party stuff, but also Newtonsoft.Json v 6.0.8 full ($packagesFolder\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll)
Project 4 - MyWebsite.Tests
To test the web project, I have a test project that calls endpoints using Custom.WebApi implementation. This project also references newtonsoft.json version 6.0.8. However, this references is purely to fix errors observed when running. Nothing in this project depends on Newtonsoft.Json, but if I do not explicitly add a reference to it, it will fail with TypeLoadException. Adding the reference seems to make that go away.
When I run the Project 4 tests, they all fail, indicating that the website is having TypeLoadException on Startup. After a TON of investigation, I noticed that when the MyWebsite project builds, the Newtonsoft.Json.dll in the bin folder is overwritten with the portable version and fails.
If I change the test project to reference the same portable newtonsoft.json.dll, the test project fails with the same error. Using the full version, no error is observed.
If I manually replace the dll in the bin folder of MyWebsite, it is overwritten again upon build. I have made sure the references are correct in MyWebsite .csproj file, including the hint path.
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
So, either I need to resolve why it believes there is an inheritance security rule violation (looking at the source code did not reveal anything obvious about access modifiers not matching), or it needs to stop overwriting the Newtonsoft.Json.dll in the MyWebsite bin folder.
To further complicate things, this replacement only occurs SOMETIMES. If I Start Without Debugging, it seems to not happen all the time and executing the Unit Tests succeeds against the deployment when the dll is not replaced with portable version.

You can resolve this by setting "Copy Local" to false on the Newtonsoft.Json reference in your PCL projects. I'll show you tomorrow.

Related

Could not load assembly 'System.Runtime.Loader' during startup registration

When you create new Xamarin.Forms project using .NET Standard, install Castle Windsor and run the project on Android it will fail with the following error
D/Mono ( 5829): Assembly Loader probing location: 'System.Runtime.Loader'.
F/monodroid-assembly( 5829): Could not load assembly 'System.Runtime.Loader' during startup registration.
F/monodroid-assembly( 5829): This might be due to an invalid debug installation.
F/monodroid-assembly( 5829): A common cause is to 'adb install' the app directly instead of doing from the IDE.
When I opened properties of the Android project and changed linking to Sdk and User assemblies the application ran as expected. I thought the linking option can only introduce problems as some codes won't be included, yet it fixes it.
Also, one thing to note, the previous project I worked on uses Reference whereas the newly created project uses PackageReference for nuget packages.
UPDATE: The project suddenly stopped working, removing Castle Windsor and/or changing linking options had no effect.
I did try clearing solution, nuget cache and building/running the project on different devices.
Moving back to packages.config nuget management fixed the problem.

Why isn't ASP.NET app throwing a System.IO.FileLoadException?

We have an ASP.NET app with N number of projects. Two projects both reference a third party library - DocumentFormat.OpenXml.dll. One project - project A - references version 2.0.5022.0 of the library. Another project - project B - references version 2.5.5631.0 of the library. We get a build warning when the solution is built about the conflict between the two versions of the same DLL. Version 2.5.5631.0 is the version that ends up in the \bin directory.
At runtime, when I test the functionality provided by assembly A (built from project A) on an internal QA server, the functionality works. However, that's not what I expected. I expected to get a System.IO.FileLoadException error:
System.IO.FileLoadException: Could not load file or assembly 'DocumentFormat.OpenXml, Version=2.0.5022.0...
Note that there are no bindingRedirects for this DLL in the web.config file of the app.
The reason why this issue came to my attention is that we are in fact getting the System.IO.FileLoadException error message on a customer's server. I can't understand why we're not getting the same error on our QA server. Any ideas?

System.Web.MVC not copied into bin folder since MS14-059. How to protect against creating builds with missing DLLs as a result of Windows Updates?

This morning it was reported that our web app on our QA server was completely broken with the following error reported from Web.config:
Could not load file or assembly 'System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified
Remembering seeing a Windows Update that mentioned MVC, I did some digging and found lots of people reporting a recent Windows Update breaking MVC.
After much digging through those questions and our server, it seems that what's bitten us does not match what's in those other questions, but it does appear related. Here's what we think know:
Our app that is broken uses ASP.NET MVC 5.1
MVC was installed via NuGet
Our BuildServer and QA servers do NOT have MVC 5.1 installed (therefore, not GAC'd)
What we believe has broken caused the "bad build" to be created:
A patch for MVC 5.1 was installed on the BuildServer via Windows Update despite not having MVC 5.1 installed in the GAC
The patch has put the "updated" version of MVC 5.1 in the GAC
CopyLocal=true is ignored when a DLL is in the GAC; therefore since the patch, this means that builds of our app from the BuildServer no longer have System.Web.MVC in the output folder
Since System.Web.MVC is not in the GAC on our QA servers (they have not yet been patched), the application now fails, because System.Web.MVC cannot be found
Assuming the behavior described above is correct, this means that any time MS service a NuGet DLL via Windows Update that we do not have in the GAC, our BuildServer will start producing incomplete builds (missing out those DLLs that have been injected into the GAC).
Upgrading to MVC 5.2 solves this issue (likely because it wasn't patched, and was therefore not injected into the GAC); the DLL is now copied to the output folder. There are no changes in the diff that upgraded to 5.2.2 except for version number changes (there's specifically no <Private> node been added/edited).
We do not wish to start GACing everything, nor creating manual build steps to copy all of our DLLs into the bin folder just in case MS patches them.
So, what can we change today to ensure we don't ever end up with out BuildServer silently producing back bad builds if MS patch other DLLs in the future?
A patch for MVC 5.1 was installed on the BuildServer via Windows Update despite not having MVC 5.1 installed in the GAC
Yes, this behavior is actually by design. See http://blogs.msdn.com/b/dotnet/archive/2014/01/22/net-4-5-1-supports-microsoft-security-updates-for-net-nuget-libraries.aspx.
The patch has put the "updated" version of MVC 5.1 in the GAC
Yes, that's correct; it's how the patch gets the updated code to run instead of the old code. See https://technet.microsoft.com/en-us/library/security/ms14-059.
CopyLocal=true is ignored when a DLL is in the GAC; therefore since the patch, this means that builds of our app from the BuildServer no longer have System.Web.MVC in the output folder
Not exactly. What actually happens is a project that previously was CopyLocal=true gets switched to CopyLocal=false. CopyLocal can be set in one of two ways: 1) If there's an explicit <Private>True</Private> setting in the .csproj file, or 2) By default, if no such setting exists (GAC'd assemblies do not CopyLocal by default; other assemblies do).
So what appears to have happened in this case is that your project file didn't have this setting in the csproj file. As a result, the GUI showed the setting based on the evaluated default value before the patch (CopyLocal = true) but then after the patch was installed, the GUI will now show the new default value for a GAC'd assembly (CopyLocal = false).
Since System.Web.MVC is not in the GAC on our QA servers (they have not yet been patched), the application now fails, because System.Web.MVC cannot be found
That's correct.
Assuming the behavior described above is correct, this means that any time MS service a NuGet DLL via Windows Update that we do not have in the GAC, our BuildServer will start producing incomplete builds (missing out those DLLs that have been injected into the GAC).
For any .csproj reference without an explicit <Private>True</Private> setting, that is correct. Also, note the using NuGet to update your MVC reference can remove this setting even if it was previously present. See http://nuget.codeplex.com/workitem/4344.
Upgrading to MVC 5.2 solves this issue (likely because it wasn't patched, and was therefore not injected into the GAC); the DLL is now copied to the output folder. There are no changes in the diff that upgraded to 5.2.2 except for version number changes (there's specifically no node been added/edited).
That's correct. Since MVC 5.2 is not GAC'd, even without an explicit <Private>True</Private> setting, the default value of this non-GAC'd assembly will be CopyLocal=true.
We do not wish to start GACing everything, nor creating manual build steps to copy all of our DLLs into the bin folder just in case MS patches them.
So, what can we change today to ensure we don't ever end up with out BuildServer silently producing back bad builds if MS patch other DLLs in the future?
The best you can do today is:
Put explicit <Private>True</Private> settings in your .csproj file for all your NuGet package assembly references.
Until NuGet bug #4344 is fixed, any time you use NuGet to update a package reference, go back into your .csproj file and re-add the explicit <Private>True</Private> setting.
I believe this issue is addressed in the .Net Web development tools and UI blog here: link
I won't repeat the whole thing here, as the issue and resolution is explained pretty well at that link.
However just to repeat the key points, which should explain why this has happened:
As part of patch KB2994397 MVC 5.1 was added to the GAC.
There appears to be a NuGet bug that resets CopyLocal flag. (see link ) This means that when a machine with the above patch deploys to a non-patched machine it will break!
MVC 4 has had its assembly version number incremented by the same security update - MS14-059 (so the GAC version will NOT be used) This explains why the MVC 4 version still works - despite it being in the GAC.
I added a note about this issue in my blog:
Microsoft Asp.Net MVC Security Update MS14-059 broke my build!.
Your analysis of the problem is right on the money, by default the Copy Local flag is set to false when the assembly is in the GAC, manually setting it to true should fix this problem.
Upgrading to 5.2.2 is even better, you get the benefits of the new release in addition to the security fix.

Compiling ASP.NET project versus NET4.0 with NET4.5 installed

I have an ASP.NET project that was working correctly compiled with Visual Studio 2010 and NET4.0.
Then I have installed VS Express 2012 and NET4.5 and I always get an Exception trying to open a SqlConnection.
Can I have some chance to recompile my project targeting NET4.0 (so without disinstalling 4.5) and have it working?
In VS Express 2012 I have this web.config:
<system.web>
<compilation debug="true" targetFramework="4.0"/>
The referenced assemblies correctly target the v4.0, for example:
Assembly System.Data
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.dll
EDIT 2
As this blog http://blogs.msdn.com/b/msbuild/archive/2007/04/12/new-reference-assemblies-location.aspx and also this answer https://stackoverflow.com/a/8543850/1012244 explains very well, there is a BIG difference betweeen Referenced Assemblies (folder contains those assemblies that ship with the x.xx Framework which are useful for referencing during the design and build of new components) and Runtime scenario (At runtime, these components will still be loaded from the GAC in most cases).
However, when I run the project I always get the Exception, as if the project actually was using NET4.5... Why?
PS. If I deploy this project on a production server machine with only NET4.0 installed, the connection is fine.
(This is clear now: Installing Net4.5 essentially replaces Net4.0)
UPDATED QUESTION -
Can I have some chance to recompile my project targeting an OLD NET4.0 .dll (System.Data.dll in my case) instead of the new Net4.5 dll?
EDIT - Additional info
At this MSDN link http://msdn.microsoft.com/en-us/library/ff602939.aspx I found:
If you determine that a change in the .NET Framework 4.5 has broken your application, check the Runtime Settings Schema to determine whether you can use a runtime setting in your application configuration file to restore the previous behavior.
Could this help me? And how?

ASP.Net build error - assembly not referenced

I am getting a build error when I attempt to build my asp.net application. The error is:
The type 'MediCare.Framework.Authentication.IUserAuthenticate' is defined in an assembly that is not referenced. You must add a reference to assembly 'MediCare.Framework, Version=1.0.1.95, Culture=neutral, PublicKeyToken=1999fa3c42b9'.
I can see the class in the library which is in the references folder. How do I debug this issue?
My intention is to point the references folder to the library source code's bin directory (since the pdb file is lcoated there and any updates to the library will reflect in the application). However, when I point the references folder to the bin directory of the source code, I get the error message above.
Update The application was originally developed in VS 2008 and I am modifying it in 2010. I think I am confused about where the GAC assemblies would be, if I am using VS 2010 (2.0 framework location or 4.0 framework location) ? .NET 4.0 has a new GAC, why?
Update (06-26-2012)
The file in the GAC ("C:\Windows\assembly\") has been deleted. But this error is still occuring.
This could possibly be caused by version inconsistencies. Meaning, in order to fix this, I would do a complete clean build of your assemblies (and also an assemblies that might be nested inside an assembly). Just go out cold and do a new build on all assemblies. That should work.
Go into windows explorer, right click on the DLL file that your project is using that contains this class, and look at the version tab. Make sure version number matches what you see in the error message. My guess is that it won't.
If it does match, then check the GAC and make sure there isn't a different version of the DLL there that it could be picking up. To do that, go to windows explorer, and navigate to c:\windows\assembly. See if that assembly is in there with a different version number. If it is, you may need to delete it from the GAC (use caution though because other apps may depend on it being there).

Resources