3
votes

Yes, I went through the questions with similar titles. None of them seem to match the situation I'm in. It's simply the programmer sending a wrong object type to the view.

This is the exact error message I'm receiving:

The model item passed into the dictionary is of type 'IS.Extensions.Models.ContactSelectList', but this dictionary requires a model item of type 'IS.Extensions.Models.ContactSelectList'.

I started moving around views and model classes in our solution in an attempt to make it 'framework-like'. With this I mean that some views/models we have are used in multiple MVC applications and some views/models are specific for a certain MVC application.
The issue started áfter moving the ContactSelectList view.
Common views are in a project that uses the Razor generator to compile them.

I have this in my view:

@model IS.Extensions.Models.ContactSelectList

and when debugging I can see that the model I'm sending to the RenderPartial method is of THE SAME TYPE: enter image description here

Some sidenotes:

  • IS is a MVC web app and references IS.Extensions
  • IS.Extensions is a class library referenced by IS
  • ContactSelectList.cshtml is located in IS\Views\Controls
  • The ContactSelectList.cs model class is located in IS.Extensions\Models
  • The 'parent view' (the view that triggers this RenderPartial call is situated in the 'common' project: ZModel.Web\Views\Controls

Does anyone have any idea what's going on here? The error messages is kinda confusing and not really a help..

Edit after Erics comment:

The assembly containing the model class (ContactSelectList.cs) is dynamically loaded. Why? Because I thought it makes sense to create a kind of extension / plugin system, where dropping a certain dll in a certain directory extends the common models with some application specific ones.
This is how (slightly modified):

var zExtenderAssembly = Assembly.LoadFile(path);
extenderType = zExtenderAssembly.GetTypes().ToList().Where(t => t.GetInterface("IZExtender") != null).FirstOrDefault();
return (Activator.CreateInstance(extenderType) as IZExtender).CreateBO("ContactSelectList");

The 'CreateBo' method in the ZExtender (implements IZExtender) simply creates a new instance of a ContactSelectList (which is in the same library as the ZExtender, so no reflection needed):

public Component CreateBO(string name)
{
    ...
            return new ContactSelectList();
    ...
}
1
Just a guess: are you by chance using reflection? Are you by chance obtaining two copies of the assembly containing the type, one via loading an assembly by its path, and one via loading the same assembly by its assembly name? If you do that then reflection will consider types from the two loadings of the same assembly to be different types. Any assembly loaded from its path is considered to be distinct from an assembly loaded by its assembly name. That can cause this sort of error message. It was super confusing the first time it happened to me.Eric Lippert
@Eric: I'm only creating a ContactSelectList object once. The thing it's colliding with is merely the declaration in the view. It could be indeed something related to how the object is created. See my edited question. Can you think of any way around it?TweeZz
Woo hoo, my psychic powers are apparently strong today. Doing a "LoadFrom" is almost certainly the cause of this problem. Can you do a load by the assembly name rather than its path? If you do that then the loader will say "ah, I see we've loaded this thing by its name twice, let's just use the types we've already loaded".Eric Lippert
More generally: if you are building your own addin system you might consider using MEF or MAF as a starting point rather than trying to roll your own. Having built one addin system myself (that was the precursor to MAF) I can tell you, you'll run into a lot of these sorts of tricky issues.Eric Lippert
@Eric: will come back to this tmrw.. need to go home now :) This is a case where I wish SO had some private messaging system.. This comment only to tell Eric that I'm not yet finished communicating about this ;) I guess I will delete this comment tomorrow :)TweeZz

1 Answers

1
votes

I moved the extension dll to the bin directory of the web application and changed the way the dll is loaded.
I used to load it by specifying the full path to the .dll file. Loading the extension dll using Assembly.Load('myAssemblyName'), made everything work as before.