Quelqu'un pourrait-il clarifier quelque chose pour moi? Dans mon application ASP.NET MVC 2, j'ai une classe BaseViewModel
qui inclut la méthode suivante:
public virtual IDictionary<string, object> GetHtmlAttributes<TModel, TProperty>
(Expression<Func<TModel, TProperty>> propertyExpression)
{
return new Dictionary<string, object>();
}
L'idée étant que chaque viewmodel enfant peut remplacer cette méthode et fournir un ensemble approprié d'attributs html, basés sur une logique, à rendre dans la vue:
<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
(model => model.MyProperty)) %>
Cependant, lorsqu'il est utilisé comme dans la ligne ci-dessus, j'obtiens une erreur de compilation lorsque j'appuie sur la vue:
Les arguments de type pour la méthode '
...BaseViewModel.GetHtmlAttributes<TModel,TProperty> Expression<System.Func<TModel,TProperty>)
'ne peut pas être déduit de l'utilisation. Essayez de spécifier explicitement les arguments de type.
Je dois faire ce qui suit:
<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
<ChildModel, string>(model => model.MyProperty)) %>
Je cherche juste une certaine clarté sur la façon dont il essaie d'inférer le type, il n'a aucun problème à le faire dans le HtmlHelper/TextBoxFor
méthode d'extension?
Est-ce parce que HtmlHelper
dans la vue sera automatiquement pour le même type que celui spécifié dans ViewUserControl
en haut de la page, alors que mon code peut être pour tout type héritant de BaseViewModel
? Est-il possible d'écrire ceci de manière à pouvoir déduire mes types de modèle/propriété?
Dans votre exemple, le compilateur n'a aucun moyen de savoir quel type doit être TModel
. Vous pouvez faire quelque chose de proche de ce que vous essayez probablement de faire avec une méthode d'extension.
static class ModelExtensions
{
public static IDictionary<string, object> GetHtmlAttributes<TModel, TProperty>
(this TModel model, Expression<Func<TModel, TProperty>> propertyExpression)
{
return new Dictionary<string, object>();
}
}
Mais vous ne pourriez pas avoir quelque chose de similaire à virtual
, je pense.
MODIFIER:
En fait, vous pouvez faire virtual
, en utilisant des génériques auto-référentiels:
class ModelBase<TModel>
{
public virtual IDictionary<string, object> GetHtmlAttributes<TProperty>
(Expression<Func<TModel, TProperty>> propertyExpression)
{
return new Dictionary<string, object>();
}
}
class FooModel : ModelBase<FooModel>
{
public override IDictionary<string, object> GetHtmlAttributes<TProperty>
(Expression<Func<FooModel, TProperty>> propertyExpression)
{
return new Dictionary<string, object> { { "foo", "bar" } };
}
}
Je sais que cette question a déjà une réponse acceptée, mais pour moi, un débutant .NET, il y avait une solution simple à ce que je faisais mal et je pensais que je partagerais.
J'avais fait ça:
@Html.HiddenFor(Model.Foo.Bar.ID)
Ce qui a fonctionné pour moi était en train de changer:
@Html.HiddenFor(m => m.Foo.Bar.ID)
(où "m" est une chaîne arbitraire pour représenter l'objet modèle)
J'ai eu ce même problème, ma solution:
Dans le fichier web.config:
<compilation debug="true>
a dû être remplacé par<compilation debug="true" targetFramework="4.0">
Cette erreur est également liée à un problème cache.
J'ai eu le même problème et il a été résolu juste nettoyage et bâtiment la solution à nouveau.
Le compilateur C # n'a que lambda
arg => arg.MyProperty
pour déduire le type d'arg (TModel) un type d'arg.MyProperty (TProperty). C'est impossible.
Au cas où cela aiderait, j'ai rencontré ce problème en passant null
dans un paramètre pour un générique TValue
, pour contourner ce problème, vous devez convertir vos valeurs nulles:
(string)null
(int)null
etc.