43 votes

Conversion de type anonyme en dynamique

J'ai une fonction qui renvoie un type anonyme que je veux tester dans mon contrôleur MVC.

 public JsonResult Foo()
{
    var data = new
                  {
                      details = "something",
                      more = "More"
                  };
    return Json(data);
}

Je veux vérifier les données que je reçois de la fonction Foo, ce que je fais maintenant, c'est obtenir le type de données et obtenir ses valeurs de propriétés avec réflexion.

 [Test]
public void TestOne()
{
    var data = _controller.Foo().Data;
    var details = data.GetType().GetProperty("details").GetValue(data, null);
    var more = data.GetType().GetProperty("more").GetValue(data, null);

    Assert.AreEquals("something", details);
    Assert.AreEquals("More", more);
}

Existe-t-il un moyen simple similaire à celui-ci pour vérifier les propriétés anonymes ?

 [Test]
public void TestTwo()
{
    var data = (dynamic) _controller.Foo().Data;
    var details = data.details; // RunTimeBinderException object does not contain definition for details
    var more = data.more;

    Assert.AreEquals("something", details);
    Assert.AreEquals("More", more);
}

41voto

Marc Gravell Points 482669

Les objets anonymes sont internal , ce qui signifie que leurs membres sont très restreints en dehors de l'assembly qui les déclare. dynamic respecte l'accessibilité, donc prétend ne pas pouvoir voir ces membres. Si le site d'appel était dans le même assemblage, je pense que cela fonctionnerait.

Votre code de réflexion respecte l' accessibilité des membres , mais contourne l'accessibilité du type - donc cela fonctionne.

Bref : non.

26voto

Hafthor Points 5663

Ce blog avait une réponse fonctionnelle : http://blog.jorgef.net/2011/06/converting-any-object-to-dynamic.html - Merci @Jorge-Fioranelli.

 public static class DynamicExtensions {
    public static dynamic ToDynamic(this object value) {
        IDictionary<string, object> expando = new ExpandoObject();

        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
            expando.Add(property.Name, property.GetValue(value));

        return expando as ExpandoObject;
    }
}

9voto

dasblinkenlight Points 264350

Le type anonyme est un type statique régulier dans .NET, c'est juste que vous ne lui donnez pas de nom (un compilateur, cependant, le fait). C'est pourquoi le convertir en dynamic ne fonctionnera pas. Cependant, si vous contrôlez Foo() , vous pouvez construire et renvoyer un objet dynamic au lieu d'anonyme, et votre code fonctionnera. Cela devrait faire l'affaire:

 dynamic JsonResult Foo() {
    dynamic data = new ExpandoObject();
    data.details = "something";
    data.mode = "More";
    return Json(data);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X