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 开发者_Go百科(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
.
精彩评论