Додайте властивість до анонімного типу після створення


101

Я використовую анонімний об'єкт, щоб передати свої атрибути Html деяким допоміжним методам. Якщо споживач не додав атрибут ідентифікатора, я хочу додати його у своєму допоміжному методі.

Як я можу додати атрибут до цього анонімного об’єкта?

Відповіді:


17

Якщо ви намагаєтесь розширити цей метод:

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

Хоча я впевнений, що розширення об'єкта Khaja спрацює, ви можете отримати кращу ефективність, створивши RouteValueDictionary і перейшовши в об’єкт routeValues, додайте додаткові параметри з контексту, а потім поверніться, використовуючи перевантаження ActionLink, що приймає RouteValueDictionary замість об'єкта:

Для цього слід зробити фокус:

    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);
    }

Працює як шарм, це має бути прийнятою відповіддю! BTW: Якщо ви до сих пір використовуєте об'єкт перевантаження ActionLink (), вам потрібно обернути htmlAttributes за допомогою HtmlHelper.AnonymousObjectToHtmlAttributes (htmlAttributes), щоб викликати правильну перевантаження!
ДР

79

Наступний клас розширення отримає вам те, що вам потрібно.

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;
    }
}

4
100% правильно. Незважаючи на те, що зазвичай ви використовуєте анонімні типи для атрибутів Html, це насправді ідентифікатор <string, object>, і тому ви можете легко додавати / видаляти з нього.
Пітер Маннінгс

12
msdn.microsoft.com/en-us/library/… робить те ж саме, але вбудований у System.Web.Mvc.HtmlHelper.
Мир

1
Чому ToDictionary є публічним, а не приватним? Немає сенсу викривати цей метод?
професор програмування

52

Я припускаю, що тут ви маєте на увазі анонімні типи, наприклад, new { Name1=value1, Name2=value2}тощо. Якщо це так, вам не пощастило - анонімні типи - це звичайні типи, які фіксуються, складений код. Вони просто стають автогенерованими.

Що ви можете зробити, це написати, new { old.Name1, old.Name2, ID=myId }але я не знаю, чи справді ви цього хочете. Ще кілька деталей щодо ситуації (включаючи зразки коду) було б ідеально.

Крім того, ви можете створити об'єкт контейнера, у якого завжди був ідентифікатор, і будь-який інший об'єкт містив решта властивостей.


-1
public static string TextBox(this HtmlHelper html, string value, string labelText, string textBoxId, object textBoxHtmlAttributes, object labelHtmlAttributes){}

Це приймає значення id, яке має містити текстове поле, і мітка повинна посилатися. Якщо споживач зараз не включає властивість "id" у textBoxHtmlAttributes, метод створить неправильну мітку.

Я можу перевірити відображення, чи доданий цей атрибут в об’єкт labelHtmlAttributes. Якщо так, я хочу додати його або створити новий анонімний об’єкт, який його додав. Але оскільки я не можу створити новий анонімний тип, пройшовши старі атрибути та додавши власний атрибут "id", я щось застряг.

Контейнер із сильно набраним властивістю ідентифікатора, а потім анонімним набраним властивістю "атрибутів" потребує перезапису коду, який не важить до вимоги "додати поле ідентифікатора".

Сподіваюся, що ця відповідь зрозуміла. Кінець дня, більше не можу змусити мізки.


Ну ... ви можете створити новий тип (з CodeDOM тощо), який містив би відповідні властивості. Але код був би некрасивим, як чорт. Чи можу я запропонувати, що замість того, щоб взяти об'єкт і подивитися на властивості за допомогою відображення, ви взяли ідентифікатор <string, string> або щось таке? (Продовження)
Джон Скіт

Ви можете скласти цей словник за допомогою допоміжного методу, який зробив усе відображення - і, можливо, метод обгортки, який зробив саме це - але словник звучить так, що він ближче до того, що ви насправді намагаєтесь представляти; анонімні ініціалізатори об'єктів просто синтаксично зручні.
Джон Скіт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.