ASP.NET MVC에서 HTML-5 데이터 * 특성에 대시를 사용하는 방법


325

ASP.NET MVC 1 프로젝트에서 HTML5 데이터 속성 을 사용하려고합니다 . (저는 C # 및 ASP.NET MVC 초보자입니다.)

 <%= Html.ActionLink("« Previous", "Search",
     new { keyword = Model.Keyword, page = Model.currPage - 1},
     new { @class = "prev", data-details = "Some Details"   })%>

위의 htmlAttributes에서 "data-details"는 다음과 같은 오류를 발생시킵니다.

 CS0746: Invalid anonymous type member declarator. Anonymous type members 
  must be declared with a member assignment, simple name or member access.

data_details를 사용할 때 작동하지만 사양에 따라 "data-"로 시작해야한다고 생각합니다.

내 질문 :

  • 이 작업을 수행하고 Html.ActionLink 또는 유사한 Html 헬퍼와 함께 HTML5 데이터 속성을 사용하는 방법이 있습니까?
  • 사용자 정의 데이터를 요소에 첨부하는 다른 대체 메커니즘이 있습니까? 이 데이터는 나중에 JS에 의해 처리됩니다.

5
이것은 구식 답변이 포함 된 오래된 질문입니다. MVC 3 이상 사용자는이 질문을 봐야합니다. stackoverflow.com/questions/2897733/…
ED-209

답변:


115

업데이트 : MVC 3 및 ​​최신 버전은이를 지원합니다. 권장 솔루션에 대해서는 아래 JohnnyO의 높은 답변을 참조하십시오.

나는 이것을 달성하기위한 즉각적인 조력자가 없다고 생각하지만, 당신이 시도 할 두 가지 아이디어가 있습니다.

// 1: pass dictionary instead of anonymous object
<%= Html.ActionLink( "back", "Search",
    new { keyword = Model.Keyword, page = Model.currPage - 1},
    new Dictionary<string,Object> { {"class","prev"}, {"data-details","yada"} } )%>

// 2: pass custom type decorated with descriptor attributes
public class CustomArgs
{
    public CustomArgs( string className, string dataDetails ) { ... }

    [DisplayName("class")]
    public string Class { get; set; }
    [DisplayName("data-details")]
    public string DataDetails { get; set; }
}

<%= Html.ActionLink( "back", "Search",
    new { keyword = Model.Keyword, page = Model.currPage - 1},
    new CustomArgs( "prev", "yada" ) )%>

아이디어는 테스트하지 않았습니다.


5
안녕하세요. 첫 번째 접근 방식을 사용하려면 사전이 Dictionary <String, Object> 유형인지 확인하십시오.
Ondrej Stastny

40
이것이 기술적으로 작동하는 동안 권장되는 방법 (MVC 3으로 시작)은 하이픈 대신 밑줄을 사용하는 것입니다 (JohnnyO가 지적한대로).
커티스

3
위의 실제 답변을 알 까지이 선택된 답변으로 전 세계를 혼동하십시오 !
Rubens Mariuzzo

648

이 문제는 ASP.Net MVC 3에서 해결되었습니다. 이제 html 속성 속성의 밑줄을 대시로 자동 변환합니다. 밑줄이 html 속성에서 합법적이지 않기 때문에 이것에 대해 운이 좋았습니다. 따라서 MVC는 밑줄을 사용할 때 대시가 필요하다는 것을 확신 할 수 있습니다.

예를 들면 다음과 같습니다.

@Html.TextBoxFor(vm => vm.City, new { data_bind = "foo" })

MVC 3에서 이것을 렌더링합니다 :

<input data-bind="foo" id="City" name="City" type="text" value="" />

여전히 이전 버전의 MVC를 사용하는 경우 MVC3의 소스 코드에서 빌린이 정적 메서드를 만들어 MVC 3이 수행하는 작업을 모방 할 수 있습니다.

public class Foo {
    public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes) {
        RouteValueDictionary result = new RouteValueDictionary();
        if (htmlAttributes != null) {
            foreach (System.ComponentModel.PropertyDescriptor property in System.ComponentModel.TypeDescriptor.GetProperties(htmlAttributes)) {
                result.Add(property.Name.Replace('_', '-'), property.GetValue(htmlAttributes));
            }
        }
        return result;
    }
}

그런 다음 다음과 같이 사용할 수 있습니다.

<%: Html.TextBoxFor(vm => vm.City, Foo.AnonymousObjectToHtmlAttributes(new { data_bind = "foo" })) %>

올바른 data- * 속성을 렌더링합니다.

<input data-bind="foo" id="City" name="City" type="text" value="" />

6
어떤 이유로 든 작동하지 않습니다. 소스보기에는 data_ *가 표시됩니다. MVC3 사용. 어떤 아이디어?
Simon Hartcher

안녕 시몬, 문제를 해결 했습니까? 그렇지 않은 경우 문제를 일으키는 코드를 제공 할 수 있습니까?
Johnny Oshika

아직 운이 없습니다 WebGrid.GetHtml(htmlAttributes: new { data_some : "thing" }). : '(
Rubens Mariuzzo

밑줄이 작동하는 이유를 지정하기위한 +1 HTML의 속성 이름에서 밑줄이 유효하지 않은 것으로 나타났습니다!
Umar Farooq Khawaja

2
@RubensMariuzzo 이것은 RouteValueDictionaryMVC3의 Html.Something()방법 으로 구워지지 않았습니다 . 그것은 그 가능성이 WebGrid같은 방식으로 업그레이드하지 않은, 또는 당신은의 버전을 확인할 수 있습니다System.Web.Helpers.dll
키스

58

위에서 제안한 것보다 훨씬 쉽습니다. 대시 (-)를 포함하는 MVC의 데이터 속성은 밑줄 (_)을 사용하여 제공됩니다.

<%= Html.ActionLink("« Previous", "Search",
 new { keyword = Model.Keyword, page = Model.currPage - 1},
 new { @class = "prev", data_details = "Some Details"   })%>

나는 JohnnyO가 이미 이것을 언급 한 것을 본다.


12
HtmlHelper.AnonymousObjectToHtmlAttributes (object)는 사용자 정의 확장이 밑줄을 하이픈으로 바꾸지 않는 이유가 궁금한 경우에 대비합니다.
Nikkelmann 2016 년

1
이것은 가장 간단한 답변이며 완벽하게 작동하기 때문에 투표가 필요합니다!
Dan Diplo

21

mvc 4에서 밑줄 ( "_")로 렌더링 할 수 있음

면도칼:

@Html.ActionLink("Vote", "#", new { id = item.FileId, }, new { @class = "votes", data_fid = item.FileId, data_jid = item.JudgeID, })

렌더링 된 HTML

<a class="votes" data-fid="18587" data-jid="9" href="/Home/%23/18587">Vote</a>

안녕하세요, Ajax 또는 제출을 통해 컨트롤러에 데이터 RFID를 POST하는 방법이 있습니까? 데이터 활용 방법이 궁금합니다. 예를 들어 data-date속성에 속성 이 있으면 컨트롤러 / 액션에 어떻게 게시 할 수 있습니까? 또한 거기에 % 23은 무엇입니까
트랜스포머

예, 양식 수집을 사용하여 ID 또는 이름으로 액세스하십시오. % 23은 #
mzonerz입니다.

4

이를 새로운 Html 헬퍼 확장 기능으로 구현하면 기존 ActionLink와 유사하게 사용됩니다.

public static MvcHtmlString ActionLinkHtml5Data(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes, object htmlDataAttributes)
{
    if (string.IsNullOrEmpty(linkText))
    {
        throw new ArgumentException(string.Empty, "linkText");
    }

    var html = new RouteValueDictionary(htmlAttributes);
    var data = new RouteValueDictionary(htmlDataAttributes);

    foreach (var attributes in data)
    {
        html.Add(string.Format("data-{0}", attributes.Key), attributes.Value);
    }

    return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null, actionName, controllerName, new RouteValueDictionary(routeValues), html));
}

그리고 당신은 그렇게 그렇게 부릅니다 ...

<%: Html.ActionLinkHtml5Data("link display", "Action", "Controller", new { id = Model.Id }, new { @class="link" }, new { extra = "some extra info" })  %>

단순 :-)

편집하다

여기에 조금 더 쓰기


3

Url.Action에서 와 같이 일반 하이퍼 링크를 사용하여 끝났습니다 .

<a href='<%= Url.Action("Show", new { controller = "Browse", id = node.Id }) %>'
  data-nodeId='<%= node.Id %>'>
  <%: node.Name %>
</a>

그것은 더 a나쁘지만 태그를 약간 더 제어 할 수 있으며 때로는 AJAXified 사이트에서 유용합니다.

HTH


0

나는 순수한 "a"태그, 너무 많은 타이핑을 사용하는 것을 좋아하지 않습니다. 그래서 해결책이 있습니다. 보기에 그것은 보인다

<%: Html.ActionLink(node.Name, "Show", "Browse", 
                    Dic.Route("id", node.Id), Dic.New("data-nodeId", node.Id)) %>

Dic 클래스의 구현

public static class Dic
{
    public static Dictionary<string, object> New(params object[] attrs)
    {
        var res = new Dictionary<string, object>();
        for (var i = 0; i < attrs.Length; i = i + 2)
            res.Add(attrs[i].ToString(), attrs[i + 1]);
        return res;
    }

    public static RouteValueDictionary Route(params object[] attrs)
    {
        return new RouteValueDictionary(Dic.New(attrs));
    }
}

1
분명히 더 좋은 클래스 이름이 있습니다 ... t최소한 추가 클래스가 있습니다 !
hvaughan3

-2

다음과 같이 사용할 수 있습니다.

Mvc에서 :

@Html.TextBoxFor(x=>x.Id,new{@data_val_number="10"});

HTML에서 :

<input type="text" name="Id" data_val_number="10"/>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.