101 votes

Ajouter une propriété au type anonyme après sa création

J'utilise un objet anonyme pour transmettre mes attributs Html à certaines méthodes d'aide. Si le consommateur n'a pas ajouté l'attribut ID, je veux l'ajouter dans ma méthode d'aide.

Comment puis-je ajouter un attribut à cet objet anonyme ?

77voto

Khaja Minhajuddin Points 2797

La classe d'extension suivante vous permettra d'obtenir ce dont vous avez besoin.

public static class ObjectExtensions
{
    public static IDictionary<string, object> AddProperty(this object obj, string name, object value)
    {
        var dictionary = obj.ToDictionary();
        dictionary.Add(name, value);
        return dictionary;
    }

    // helper
    public static IDictionary<string, object> ToDictionary(this object obj)
    {
        IDictionary<string, object> result = new Dictionary<string, object>();
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(obj);
        foreach (PropertyDescriptor property in properties){
            result.Add(property.Name, property.GetValue(obj));
        }
        return result;
    }
}

50voto

Jon Skeet Points 692016

Je suppose que vous voulez parler ici de types anonymes, par ex. new { Name1=value1, Name2=value2} etc. Si c'est le cas, vous n'avez pas de chance - les types anonymes sont des types normaux en ce sens qu'il s'agit de code fixe et compilé. Ils sont simplement autogénérés.

Ce que vous pourrait faire est écrire new { old.Name1, old.Name2, ID=myId } mais je ne sais pas si c'est vraiment ce que tu veux. Un peu plus de détails sur la situation (y compris des échantillons de code) serait idéal.

Alternativement, vous pouvez créer un objet conteneur qui toujours avait un ID et un autre objet contenait le reste des propriétés.

16voto

Levitikon Points 2258

Si vous essayez d'étendre cette méthode :

public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues);

Bien que je sois sûr que les extensions Object de Khaja fonctionneraient, vous pourriez obtenir de meilleures performances en créant un RouteValueDictionary et en passant dans l'objet routeValues, ajouter vos paramètres supplémentaires à partir du Contexte, puis retourner en utilisant la surcharge ActionLink qui prend un RouteValueDictionary au lieu d'un objet :

Cela devrait faire l'affaire :

    public static MvcHtmlString MyLink(this HtmlHelper helper, string linkText, string actionName, object routeValues)
    {
        RouteValueDictionary routeValueDictionary = new RouteValueDictionary(routeValues);

        // Add more parameters
        foreach (string parameter in helper.ViewContext.RequestContext.HttpContext.Request.QueryString.AllKeys)
        {
            routeValueDictionary.Add(parameter, helper.ViewContext.RequestContext.HttpContext.Request.QueryString[parameter]);
        }

        return helper.ActionLink(linkText, actionName, routeValueDictionary);
    }

-1voto

Boris Callens Points 17660
public static string TextBox(this HtmlHelper html, string value, string labelText, string textBoxId, object textBoxHtmlAttributes, object labelHtmlAttributes){}

Cela permettrait d'accepter la valeur "id" que la zone de texte devrait avoir et à laquelle l'étiquette devrait faire référence. Si le consommateur n'inclut pas la propriété "id" dans les textBoxHtmlAttributes, la méthode créera une étiquette incorrecte.

Je peux vérifier par réflexion si cet attribut est ajouté dans l'objet labelHtmlAttributes. Si c'est le cas, je veux l'ajouter ou créer un nouvel objet anonyme qui l'a ajouté. Mais comme je ne peux pas créer un nouveau type anonyme en parcourant les anciens attributs et en ajoutant mon propre attribut "id", je suis un peu coincé.

Un conteneur avec une propriété ID fortement typée puis une propriété "attributs" typée anonymement nécessiterait des réécritures de code qui ne sont pas à la hauteur de l'exigence "ajouter un champ ID".

J'espère que cette réponse est compréhensible. C'est la fin de la journée, je n'arrive plus à mettre mon cerveau en ligne

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