2010-09-01 6 views
2

Je reçois une exception particulière en utilisant la méthode Html.RenderPartial. ASP.NET MVC semble être incapable d'un objet de type ClassA à un objet de type ClassA. Je me demandais si quelqu'un sait ce qui se passe.ASP.NET MVC: L'élément de modèle transmis au dictionnaire est de type 'ClassA', mais ce dictionnaire nécessite un élément de modèle de type 'ClassA'

Voici un peu plus d'information de fond. Je vais avoir la hiérarchie suivante en place:

public interface IInterface 
{ 
    string Name { get; } 
} 

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

L'utilisation de ces deux dans une vue:

<%@ 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> 

Et ayant un UserControl nommé ClassAUserControl avec cet en-tête:

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

Edit: TypeHelpers.IsCompatibleObject (Valeur d'objet) décide que les deux types sont différents:

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

Dans le cas ci-dessus, T est ClassA et le type de valeur est ClassA. Cela fait vraiment me demande pourquoi 'valeur est T' échoue ...

+0

http://stackoverflow.com/questions/2315129/the-model-item-passed-into-the-dictionary-is-of-type-mvc-models-modela-but-thi/2479865 # 2479865 peut vous être utile – Maslow

Répondre

0

Vous devez changer:

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

à

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

Il ne sait pas que votre objet IInterface est aussi un ClassA .

ou changement:

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

à la coulée (échouera s'il existe des objets qui ne sont pas ClassA

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

ou bien la meilleure solution (si vous vous attendez d'autres types de ClassA)

foreach (IInterface item in Model) 

à

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

cela ne passera que par les éléments de type ClassA.

+0

Merci pour votre réponse rapide, mais l'idée était de garder la vue inaperçue des implémentations de IInterface, et de laisser déléguer tout le rendu spécifique aux vues partielles. Ce changement casserait ma conception :-) Je sais comment résoudre le problème (rendant mon design un peu plus moche ..), encore je me demandais pourquoi ASP.NET MVC est incapable de lancer un objet de type 'ClassA' à un objet de type 'ClassA'. – Jeroen

+0

Hhm, qu'en est-il de la dernière solution que j'ai donnée?il ne prend que les classes de type 'ClassA'. Mais qu'est-ce que cela a d'important quand votre commande USB prend seulement 'ClassA'? Peut-être que vous devriez essayer: 'ViewPage >' –

+0

La vue ne peut même pas être au courant que ClassA existe, ClassA pourrait être dans une autre bibliothèque qui est chargée comme un plugin. Je voudrais garder la vue complètement dans le noir sur les implémentations de IInterface. Cela me permet d'ajouter une deuxième classe, par exemple ClassB, et d'ajouter une deuxième vue partielle (ClassBUserControl). La vue sera alors capable de rendre les deux vues partielles sans aucun changement. Je vais essayer d'utiliser l'approche dynamique que vous avez suggérée. – Jeroen

1

Votre commande usercontrol attend un objet ClassA alors que vous lui donnez un objet IInterface. Il ne peut pas l'abaisser à l'objet A parce qu'il ne peut pas savoir qu'il s'agit d'une classe A. Vous pourriez faire quelque chose du genre en utilisant la réflexion pour refondre votre interface pour récupérer votre type ClassA, mais ce serait si moche que je préfère ne pas penser une autre seconde ...

Questions connexes