Oluşturulduktan sonra anonim türe özellik ekleyin


101

Html Özniteliklerimi bazı yardımcı yöntemlere geçirmek için anonim bir nesne kullanıyorum. Tüketici bir kimlik özelliği eklemediyse, bunu yardımcı yöntemime eklemek istiyorum.

Bu anonim nesneye nasıl öznitelik ekleyebilirim?

Yanıtlar:


17

Bu yöntemi genişletmeye çalışıyorsanız:

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

Khaja'nın Object uzantılarının çalışacağından emin olsam da, bir RouteValueDictionary oluşturup routeValues ​​nesnesini ileterek daha iyi performans elde edebilir, ek parametrelerinizi Context'ten ekleyebilir, ardından bir nesne yerine RouteValueDictionary alan ActionLink aşırı yüklemesini kullanarak geri dönebilirsiniz:

Bu hile yapmalı:

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

Bir cazibe gibi çalışıyor, bu kabul edilen cevap olmalı! BTW: Şimdiye kadar ActionLink () 'in nesne aşırı yüklemelerini kullanıyorsanız, doğru aşırı yüklemeyi çağırmak için htmlAttributes'ı HtmlHelper.AnonymousObjectToHtmlAttributes (htmlAttributes) ile sarmalamanız gerekir!
DR

79

Aşağıdaki uzatma sınıfı size ihtiyacınız olanı verecektir.

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 doğru. Html Öznitelikleri için genellikle anonim türler kullansanız da, bu aslında bir IDictionary <dize, nesne> dir ve bu nedenle kolayca ekleyebilir / kaldırabilirsiniz.
Peter Munnings

12
msdn.microsoft.com/en-us/library/… aynı şeyi yapar, ancak System.Web.Mvc.HtmlHelper'da yerleşiktir.
Mir

1
ToDictionary neden herkese açık ve özel değil, bu yöntemi ifşa etmek mantıklı değil?
programlama profesörü

52

Burada anonim türleri kastettiğinizi varsayıyorum, örn new { Name1=value1, Name2=value2}. Eğer öyleyse, şansınız kalmaz - anonim türler sabit, derlenmiş kod oldukları için normal türlerdir. Sadece otomatik olarak oluşturuldular.

Ne olabilir yapmak yazma olduğunu new { old.Name1, old.Name2, ID=myId }ama bu istediğin gerçekten buysa bilmiyorum. Durumla ilgili daha fazla ayrıntı (kod örnekleri dahil) ideal olacaktır.

Alternatif olarak, her zaman bir kimliği olan ve özelliklerin geri kalanını içeren diğer nesneler olan bir konteyner nesnesi oluşturabilirsiniz .


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

Bu, metin kutusunun sahip olması gereken ve etiketin başvurması gereken kimlik değerini kabul eder. Tüketici artık textBoxHtmlAttributes'a "id" özelliğini dahil etmezse, yöntem yanlış bir etiket oluşturacaktır.

Bu özniteliğin labelHtmlAttributes nesnesine eklenip eklenmediğini yansıtmayı kontrol edebilirim. Öyleyse, eklemek veya eklenmiş olan yeni bir anonim nesne oluşturmak istiyorum. Ancak eski öznitelikler arasında dolaşıp kendi "id" özniteliğimi ekleyerek yeni bir anonim tür oluşturamadığım için, biraz sıkıştım.

Kesin olarak yazılmış bir kimlik özelliğine ve ardından anonim olarak yazılmış "özniteliklere" sahip bir kap, "kimlik alanı ekle" gereksinimini karşılamayan kodların yeniden yazılmasını gerektirecektir.

Umarım bu yanıt anlaşılırdır. Günün sonu, artık beynimi sıraya sokamıyorum ..


Pekala ... olabilir alakalı özelliklerini içeriyordu (CodeDOM vb ile) yeni bir tür oluşturmak. Ama kod cehennem kadar çirkin olurdu. Bir nesneyi alıp özelliklere yansıma yoluyla bakmak yerine, bir IDictionary <string, string> veya başka bir şey almanızı önerebilir miyim? (Devam)
Jon Skeet

Bu sözlüğü, tüm yansıtma işini yapan yardımcı bir yöntemle oluşturabilirsiniz - ve muhtemelen tam olarak bunu yapan bir sarmalayıcı yöntemine sahip olabilirsiniz - ama bir sözlük, gerçekten temsil etmeye çalıştığınız şeye daha yakın gibi geliyor; anonim nesne başlatıcıları sözdizimsel olarak kullanışlıdır.
Jon Skeet
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.