เพิ่มคุณสมบัติให้กับชนิดที่ไม่ระบุชื่อหลังการสร้าง


101

ฉันใช้ออบเจ็กต์ที่ไม่ระบุชื่อเพื่อส่งต่อคุณสมบัติ Html ของฉันไปยังวิธีการช่วยเหลือบางอย่าง หากผู้บริโภคไม่ได้เพิ่มแอตทริบิวต์ ID ฉันต้องการเพิ่มในวิธีการช่วยเหลือของฉัน

ฉันจะเพิ่มแอตทริบิวต์ให้กับวัตถุที่ไม่ระบุตัวตนนี้ได้อย่างไร

คำตอบ:


17

หากคุณกำลังพยายามขยายวิธีการนี้:

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

แม้ว่าฉันแน่ใจว่าส่วนขยาย Object ของ 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) เพื่อเรียกโอเวอร์โหลดที่ถูกต้อง!
DR

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 แต่จริงๆแล้วมันเป็น IDictionary <string, object> ดังนั้นคุณจึงสามารถเพิ่ม / ลบออกได้อย่างง่ายดาย
Peter Munnings

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 }แต่ผมไม่ทราบว่าที่จริงสิ่งที่คุณต้องการ รายละเอียดเพิ่มเติมเกี่ยวกับสถานการณ์ (รวมถึงตัวอย่างโค้ด) จะเหมาะอย่างยิ่ง

หรือคุณสามารถสร้างอ็อบเจ็กต์คอนเทนเนอร์ที่มี ID เสมอและอ็อบเจ็กต์อื่น ๆ ที่มีคุณสมบัติที่เหลืออยู่


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

สิ่งนี้จะยอมรับค่ารหัสที่กล่องข้อความควรมีและป้ายกำกับควรอ้างถึง หากผู้บริโภคไม่รวมคุณสมบัติ "id" ใน textBoxHtmlAttributes เมธอดจะสร้างป้ายกำกับที่ไม่ถูกต้อง

ฉันสามารถตรวจสอบผ่านการสะท้อนหากมีการเพิ่มแอตทริบิวต์นี้ในออบเจ็กต์ labelHtmlAttributes ถ้าเป็นเช่นนั้นฉันต้องการเพิ่มหรือสร้างวัตถุใหม่ที่ไม่ระบุชื่อที่ได้เพิ่มเข้าไป แต่เนื่องจากฉันไม่สามารถสร้างประเภทที่ไม่ระบุตัวตนใหม่โดยการเดินผ่านแอตทริบิวต์เก่าและเพิ่มแอตทริบิวต์ "id" ของตัวเองฉันจึงติดขัด

คอนเทนเนอร์ที่มีคุณสมบัติ ID ที่พิมพ์อย่างรุนแรงและคุณสมบัติ "แอตทริบิวต์" ที่พิมพ์โดยไม่ระบุตัวตนจะต้องมีการเขียนโค้ดใหม่ที่มีน้ำหนักไม่ถึงข้อกำหนด "เพิ่มฟิลด์รหัส"

หวังว่าคำตอบนี้จะเข้าใจได้ สิ้นวันสมองไม่ไหวแล้ว ..


ดี ... คุณสามารถสร้างประเภทใหม่ (ด้วย CodeDOM ฯลฯ ) ซึ่งมีคุณสมบัติที่เกี่ยวข้อง แต่รหัสจะน่าเกลียดเป็นนรก ฉันขอแนะนำว่าแทนที่จะถ่ายวัตถุและดูคุณสมบัติผ่านการสะท้อนคุณใช้ IDictionary <string, string> หรืออะไรก็ได้? (ต่อ)
Jon Skeet

คุณสามารถสร้างพจนานุกรมนั้นขึ้นมาด้วยวิธีการผู้ช่วยซึ่งทำสิ่งสะท้อนทั้งหมด - และอาจมีวิธีการห่อหุ้มซึ่งทำได้อย่างแม่นยำ แต่พจนานุกรมดูเหมือนว่ามันใกล้เคียงกับสิ่งที่คุณพยายามจะเป็นตัวแทนจริงๆ ตัวเริ่มต้นอ็อบเจ็กต์ที่ไม่ระบุชื่อมีประโยชน์ในเชิงไวยากรณ์
Jon Skeet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.