ASP.NET MVC에서 HTML-5 데이터 * 특성에 대시를 사용하는 방법 MVC 초보자입니다.) <%= Html.ActionLink(“« Previous”,

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에 의해 처리됩니다.


답변

업데이트 : 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" ) )%>

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


답변

이 문제는 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="" />


답변

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

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

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


답변

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>


답변

이를 새로운 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" })  %>

단순 🙂

편집하다

여기에 조금 더 쓰기


답변

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

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

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

HTH


답변

나는 순수한 “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));
    }
}