생성 후 익명 유형에 속성 추가


101

익명 개체를 사용하여 내 Html 특성을 일부 도우미 메서드에 전달합니다. 소비자가 ID 속성을 추가하지 않은 경우 도우미 메서드에 추가하고 싶습니다.

이 익명 개체에 속성을 추가하려면 어떻게해야합니까?

답변:


17

이 방법을 확장하려는 경우 :

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

Khaja의 Object 확장이 작동 할 것이라고 확신하지만 RouteValueDictionary를 만들고 routeValues ​​개체를 전달하고 Context에서 추가 매개 변수를 추가 한 다음 개체 대신 RouteValueDictionary를 사용하는 ActionLink 오버로드를 사용하여 반환하면 더 나은 성능을 얻을 수 있습니다.

이것은 트릭을 수행해야합니다.

    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에 내장되어 있습니다.
Mir

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에 "id"속성을 포함하지 않는 경우 메서드는 잘못된 레이블을 만듭니다.

이 특성이 labelHtmlAttributes 개체에 추가되었는지 리플렉션을 통해 확인할 수 있습니다. 그렇다면 추가하거나 추가 된 새 익명 개체를 만들고 싶습니다. 하지만 이전 속성을 살펴보고 내 자신의 "id"속성을 추가하여 새로운 익명 유형을 만들 수 없기 때문에 약간 갇혀 있습니다.

강력한 형식의 ID 속성과 익명 형식의 "attributes"속성이있는 컨테이너는 "add an id field"요구 사항에 맞지 않는 코드 재 작성이 필요합니다.

이 응답이 이해할 수 있기를 바랍니다. 하루가 끝났고 더 이상 내 머리를 줄 수 없습니다 ..


음 ... 관련 속성을 포함하는 새 유형 (CodeDOM 등)을 만들 있습니다. 그러나 코드는 지옥처럼 추악 할 것입니다. 객체를 가져와 반사를 통해 속성을 보는 대신 IDictionary <string, string> 또는 무언가를 취하는 것이 좋습니다. (계속)
Jon Skeet

전체 반사 작업을 수행하는 도우미 메서드를 사용하여 사전을 구축 할 수 있으며이를 정확하게 수행하는 래퍼 메서드가있을 수 있습니다. 그러나 사전은 실제로 표현하려는 것에 더 가까운 것처럼 들립니다. 익명 객체 이니셜 라이저는 구문 적으로 편리합니다.
Jon Skeet
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.