简体   繁体   中英

ASP.NET MVC: The model item passed into the dictionary is of type 'ClassA', but this dictionary requires a model item of type 'ClassA'

I'm getting a peculiar exception using the Html.RenderPartial method. ASP.NET MVC seems to be unable to an object of type ClassA to an object of type ClassA. I was wondering if anyone knows what's going on.

Here's a little more background info. I'm having the following hierarchy in place:

public interface IInterface
{
    string Name { get; }
}

public class ClassA : IInterface
{
    public string Name
    {
        get
        {
            return "ClassA ";
        }
    }
}

Using these two in a view:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<IInterface>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

<% foreach (IInterface item in Model)
   {
       Html.RenderPartial(string.Concat(item.Name, "UserControl"), item);
   }
%>

</asp:Content>

And having a UserControl named ClassAUserControl with this header:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ClassA>" %>

Edit: TypeHelpers.IsCompatibleObject(Object value) decides that the two types are different:

public static bool IsCompatibleObject<T>(object value)
{
    return ((value is T) || ((value == null) && TypeAllowsNullValue(typeof(T))));
}

In the above case T is ClassA and the type of value is ClassA. That really makes me wonder why 'value is T' fails...

Your usercontrol is expecting a ClassA Object whereas you give to it a IInterface object. He cannot downcast it to object A because he can't know it is a class A. You might do something of the kind using reflection to recast your IInterface to get back your ClassA type, but this would be so ugly I prefer not think about it another second...

You should change:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<IInterface>>" %>

to

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<ClassA>>" %>

It does not know that your IInterface object is also a ClassA .

Or change:

Html.RenderPartial(string.Concat(item.Name, "UserControl"), item);

to casting (will fail if there exists objects which are not ClassA

Html.RenderPartial(string.Concat(item.Name, "UserControl"), (ClassA)item);

or properly the best solution (if you expect other types than ClassA )

foreach (IInterface item in Model)

to

foreach (ClassA item in Model.OfType<ClassA>())

this will only go through elements of type ClassA .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM