I am trying to generate moles for the System.Web.Mvc DLL version 3, but I get the following error:
Moles : info : metadata : loading C:\TFS.as12.Projects\Project X\Main\Source\3rdPartyComponents\MVC3\System.Web.Mvc.dll
Moles : info : compilation : output assembly name: System.Web.Mvc.Moles
Moles : warning : metadata : failed to load module System.Web.Mvc.dll:
Moles : warning : metadata : Inheritance security rules violated by type: 'System.Web.Mvc.CompareAttribute'. Derived types must either match the security accessibility of the base type or be less accessible.
Moles : warning : metadata : Inheritance security rules violated by type: 'System.Web.Mvc.RemoteAttribute'. Derived types must either match the security accessibility of the base type or be less accessible.
Moles : error : code : assembly contains no types or failed to load properly
00:00:00.53> moles generator 1 errors, 3 warnings
Moles compilation FAILED - 6,18794176354816s
C:\Program Files (x86)\Microsoft Moles\bin\Microsoft.Moles.targets(79,5): error MSB3073: The command ""C:\Program Files (x86)\Microsoft Moles\bin\moles.exe" @"C:\TFS.as12.Projects\Project X\Main\Source\X.Web\X.Web.Base.Mvc.UnitTest\obj\Debug\Moles\moles.args"" exited with code -1002.
I have seen more questions about this on the Microsoft forums, but never an answer.
Does anyone have a solution?
This is related to a known issue. If you have your heart set on using Moles with MVC3, you can do the following (I have done this):
- Download the MVC3 source code.
- Remove [SecurityTransparent] from Properties/AssemblyInfo.cs
- Extract the MS public key from the real MVC dll using sn.exe: "sn -e System.Web.Mvc.dll ms_public_key.snk"
- Tell VS to use that public key when signing your fake MVC dll (you can do this under project properties, signing). Make sure you check the "delay sign only" box.
- Build. Now you have a fake MVC dll that is signed with the MS public key. But you can't use it for anything because it won't pass muster with signing verification.
- Use sn.exe again to register a skip-verification for your fake dll: "sn -Vr System.Web.Mvc.dll" <--- this needs to be your fake one
- GAC your fake one with gacutil.exe: "gacutil -if System.Web.Mvc.dll" <--- again, the fake one
- Run moles. I strongly recommend you stub/mole the entire dll because you're not going to want to have to do this again.
- Remove the skip-verification: "sn -Vu System.Web.Mvc.dll" <--- the fake one
- Restore the real dll: "gacutil -if System.Web.Mvc.dll" <--- the real one
- Delete your evil fake MVC dll lest someone accidently use it.
The System.Web.Mvc.Moles.dll you generated in step 8 will reference the real MVC dll, thanks to the public key switching you did. You can use it to stub/mole MVC classes to your heart's content.
You could try excluding problematic types:
<Moles ...
<StubGeneration ...
<Types>
<Remove TypeName="System.Web.Mvc.CompareAttribute" />
<Remove TypeName="System.Web.Mvc.RemoteAttribute" />
</Types>
<MoleGeneration>
<Types>
<Remove TypeName="System.Web.Mvc.CompareAttribute" />
<Remove TypeName="System.Web.Mvc.RemoteAttribute" />
</Types>
</MoleGeneration>
To add to what @bhamlin mentioned, in step #2, I also had to make the following changes in AssemblyInfo.cs to generate moles:
Modify
[assembly: AllowPartiallyTrustedCallers]
to
[assembly: AllowPartiallyTrustedCallers(PartialTrustVisibilityLevel = PartialTrustVisibilityLevel.NotVisibleByDefault)]
as this is what's defined in System.ComponentModel.DataAnnotations.dll
Derived types must either match the security accessibility of the base type or be less accessible
Base class for CompareAttribute, which is ValidationAttribute, is in this assembly.