2

I'm having a problem with my asp.net mvc project which is surfacing as this error:

The model item passed into the dictionary is of type 'CMS.Web.Models.Modules.RawHtmlDisplayViewModel', but this dictionary requires a model item of type 'CMS.Web.Models.Modules.RawHtmlDisplayViewModel'.

The set up is rather complicated but I've isolated the problem to do with the is keyword producing an unexpected result. CMS.Web.Models.Modules.RawHtmlDisplayViewModel inherits from CMS.Web.Models.Modules.IModuleDisplayViewModel yet for the following test code isModuleDisplayData is false, but interfaces variable does contain CMS.Web.Models.Modules.IModuleDisplayViewModel:

var isModuleDisplayData = viewModel is IModuleDisplayViewModel;
var interfaces = viewModel.GetType().GetInterfaces();

All this code is in a separate CMS project that is referenced by another project. In this project I have a CustomModuleDisplayViewModel that also inherits from IModuleDisplayViewModel and is used in the same way. This does work fine and the isModuleDisplayData check in the above code returns true.

There's a whole lot more going on than i'm able to include here, so I suppose my question is in what situation can the C# 'is' keyword fail in such a way? Trying to google 'is' hasn't proved very helpful...

Some slightly unconventional things we're doing in the project worth mentioning:

  • The module views are included as resource files in the CMS project
  • We force loading of all assemblies in the bin folder that aren't already loaded for type scanning purposes.

UPDATE:

Thank you all for replying so quickly! The namespaces are exactly the same so I would assume that if they were declared twice within the same namespace that would cause problems in compilation. In any case based on your comments I figured the dynamic loading of assemblies must be the trouble and ran a few more tests:

var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var cmsAssembly = assemblies.Where(a => a.FullName.Contains("CMS"));

It turns out the CMS assembly is loaded twice which is causing the issue. One is from the bin folder and the other is located in 'Temporary ASP.NET Files'. Looking at this question this seems to be the result of dynamic compilation of website code. I'll need to account for this somehow in my assembly loading, but does anyone know why the CMS dll would have ended up there?

Community
  • 1
  • 1
Joel Mitchell
  • 945
  • 1
  • 7
  • 19
  • 5
    Do you have multiple projects *declaring* `IModuleDisplayViewModel`? If you've got the same type in multiple assemblies, that may well be the problem. – Jon Skeet Aug 13 '14 at 12:14
  • Its possible that you need to include the namespace here also, as it must be picking up a reference to the other one – Sayse Aug 13 '14 at 12:14
  • 1
    The `is` keyword won't 'fail'. –  Aug 13 '14 at 12:14
  • 1
    Could you somehow have loaded the same interface from multiple assemblies in separate physical locations? – Rune Aug 13 '14 at 12:15
  • 3
    The problem in the **error** is not the `is`; it is the type provided to the cshtml; it sounds like `RawHtmlDisplayViewModel` has been declared in different places (or different versions), and the one provided doesn't match the one it expected - but sure, if multiple assemblies are also declaring `IModuleDisplayViewModel`, that could impact other code. – Marc Gravell Aug 13 '14 at 12:16
  • Can you provide a [minimal, complete and verifiable example](http://stackoverflow.com/help/mcve)? – dcastro Aug 13 '14 at 12:16
  • You can do the double check via Type.IsSubclassOf – Robert Aug 13 '14 at 12:29

1 Answers1

1

After spending a lot of time investigating my assembly loading code and trying to find out why duplicate assemblies would have been loaded I searched my solution for 'Assembly.Load' and found this little beauty in a class written by someone else called AssemblyResourceProvider that loads view files from an assembly:

_cmsWebAssembly = System.Reflection.Assembly.Load(System.IO.File.ReadAllBytes(Path.Combine(HttpRuntime.BinDirectory, "CMS.Web.dll")));

After I finished having a facepalm moment I replaced it with this:

_cmsWebAssembly = typeof(AssemblyResourceProvider).Assembly

This fixed the issue.

Joel Mitchell
  • 945
  • 1
  • 7
  • 19