MVC Razor dynamic model, "object" ne contient pas la définition de "PropertyName"

utilisant MVC 3 avec le moteur Razor view. J'ai ce point de vue:

@model dynamic
@{
    var products = (List<ListItemBaseModel>)Model.Products;
    var threshold = (int)(Model.Threshold ?? 1);
    var id = Guid.NewGuid().ToString();
}

il est appelé d'une autre vue en utilisant ce code:

@Html.Partial("PartialViewName", new { Products = Model, Threshold = 5 })

dans les deux vues, quand je les corrige et regarde le modèle, il semble contenir l'objet correct. Quand j'exécute le code, j'obtiens une erreur sur la ligne" var products = "disant:

'"objet" ne contient pas une définition pour 'Produits'

est-ce que quelqu'un peut expliquer à - moi pourquoi j'obtiens cette erreur? Encore une fois, quand je regarde L'objet Model en mode de débogage il a l'air tout droit (ayant 2 Propriétés: Produits et Seuil)

101
demandé sur Ruud van Falier 2011-02-01 14:47:23

7 réponses

passez-vous une instance d'une classe anonyme comme modèle de vue? J'ai juste essayé ceci (modèle de vue dynamique en CSHTML) et j'ai eu la même erreur que la vôtre en utilisant une classe anonyme, mais ça a bien marché si j'ai créé une classe nommée. J'ai cherché, mais je n'ai vu ce document nulle part.

// error
return View(new { Foo = 1, Bar = "test" });

// worked
return View(new TestClass { Foo = 1, Bar = "test" });

EDIT #1:

selon David Ebbo , vous ne pouvez pas passer un type anonyme dans une vue dynamiquement typée parce que le les types anonymes sont compilés comme internal . Puisque la vue CSHTML est compilée dans un assemblage séparé, elle ne peut pas accéder aux propriétés du type anonyme.

EDIT #2:

David Ebbo a édité son billet avec cette clarification:

Note (12/22/2011): maintenant que MVC 3 supporte directement dynamic, la technique ci-dessous n'est plus nécessaire. Ce post est en fait ce qui a conduit à l'intégration de la fonctionnalité dans MVC!

147
répondu Lucas 2014-11-17 15:33:20

sur .NET 4.0 les types anonymes peuvent facilement être convertis en ExpandoObjects et donc tous les problèmes sont résolus avec les frais généraux de la conversion elle-même. Découvrez ici

39
répondu Adaptabi 2017-05-23 12:26:06

cela n'a rien à voir avec les types anonymes ayant des propriétés internes

il est parfaitement possible passer des types anonymes d'une vue à une vue partielle

j'ai rencontré le même problème aujourd'hui et il n'était rien (directement) à faire avec le problème de passer des types anonymes et leurs propriétés inhérentes internal .

en tant que telle, en relation avec la question OPs, la réponse de @Lucas est hors de propos - même si la solution de contournement fonctionnera .

dans la question OPs, un type anonyme est passé d'un point de vue dans l'Assemblée X à un partiel dans l'Assemblée X , donc le problème que David Ebbo souligné des propriétés étant internes pour les types anonymes est sans conséquence; les types compilés pour la vue, le type partiel et le type anonyme sont tous contenus dans la même assemblée .

Alors, quelle est la cause de la défaillance soudaine de passer d'un type anonyme d'une vue partielle?

au moins dans Ma situation , j'ai découvert que c'était dû au fait d'avoir une autre vue dans le même dossier qui spécifie un type de modèle qui ne peut pas être résolu . Les vues sont compilées à l'exécution, et il serait donc logique qu'un échec à l'exécution de compiler les vues cela signifie également un échec de compiler les types dynamiques et le partiel recevrait simplement un object . Ce n'est pas immédiatement évident ce qui se passe, mais dans L'exemple spécifique de L'OPs (et le mien) c'est plus que probable la cause du problème.

il est intéressant de noter que si le type de modèle est correct mais qu'une autre partie de la vue ne se compile pas alors les types anonymes ne sont pas affectés de la même manière. Cela doit être dû à la façon dont Razor brise la compilation dynamique les composants de la vue.

une fois que vous corrigez la vue offensante, soit reconstruire la solution entière ou nettoyer et reconstruire le projet avant de vérifier si elle est fixe.

pour vous assurer que vous n'êtes pas pris par cela encore une fois, vous pouvez activer la compilation de temps de compilation de vos vues de rasoir en ajoutant ceci à votre csproj fichier:

<PropertyGroup>
    <MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>
22
répondu joshcomley 2014-02-07 17:10:58

ajouter la classe suivante n'importe où dans votre solution (utilisez l'Espace - nom du système, donc prêt à l'emploi sans avoir à ajouter de références) -

    namespace System
    {
        public static class ExpandoHelper
        {
            public static ExpandoObject ToExpando(this object anonymousObject)
            {
                IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject);
                IDictionary<string, object> expando = new ExpandoObject();
                foreach (var item in anonymousDictionary)
                    expando.Add(item);
                return (ExpandoObject)expando;
            }

        }
    }

quand vous envoyez le modèle à la vue, le convertir en Expando:

    return View(new {x=4, y=6}.ToExpando());
9
répondu Segev -CJ- Shmueli 2012-03-31 22:00:16

au lieu d'utiliser le modèle dynamic dans la vue partielle.

vous pouvez appeler les attributs des objets anonymes en utilisant @ViewData.Eval("foo") au lieu de @Model.foo .

puis vous pouvez supprimer @Model dynamic de la vue.

je suis tombé sur cette question récemment en passant quelques attributs entre les vues pour L'intégration des commentaires sociaux Facebook. Exemple de code:

Html.RenderPartial(@"Layouts/Partials/_Comments", new {currentUrl = Model.CurrentPage.GetAbsoluteUrl(), commentCount = 5 });

puis dans mon j'ai juste eu cette div:

<div class="fb-comments" data-href="@ViewData.Eval("currentUrl")" data-numposts="@ViewData.Eval("commentCount")" data-width="100%"></div>
3
répondu JamesG 2016-08-31 00:20:43

Je ne suis pas sûr que vous obtenez cette erreur parce que vous ne mettez pas en œuvre la solution de rechange. j'ai eu la même erreur dans une vue partielle. la solution était juste de nettoyer la construction et de la reconstruire. si la syntaxe est correcte, le code devrait fonctionner, mais le moteur de razor peut ne pas mettre à jour les changements de code correctement.

0
répondu goran 2013-03-27 01:22:02

pour utiliser dynamic type de référence Microsoft.CSharp assemblage

-3
répondu the_joric 2014-04-10 08:32:47