Cómo utilizar guiones en atributos de datos*HTML-5 en ASP.NET MVC




asp.net-mvc html5 (6)

En mvc 4 se podría representar con un guión bajo ("_")

Maquinilla de afeitar:

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

HTML procesado

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

Estoy tratando de usar atributos de datos HTML5 en mi proyecto ASP.NET MVC 1. (Soy un novato de C # y ASP.NET MVC).

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

Los "datos-detalles" en los atributos html anteriores dan el siguiente error:

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

Funciona cuando uso data_details, pero supongo que debe comenzar con "data-" según la especificación.

Mis preguntas:

  • ¿Hay alguna manera de hacer que esto funcione y usar atributos de datos HTML5 con Html.ActionLink o ayudantes Html similares?
  • ¿Hay algún otro mecanismo alternativo para adjuntar datos personalizados a un elemento? Estos datos serán procesados ​​más tarde por JS.

Es incluso más fácil que todo lo sugerido anteriormente. Los atributos de datos en MVC que incluyen guiones (-) se atienden con el uso de guión bajo (_).

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

Veo que JohnnyO ya mencionó esto.


No me gusta usar la etiqueta "a" pura, demasiado escribir. Así que vengo con la solución. A la vista se ve

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

Implementacion de clase 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));
    }
}

Puedes implementar esto con una nueva función de extensión de ayuda Html que luego se usará de manera similar a los ActionLinks existentes.

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

Y lo llamas así ...

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

Simples :-)

editar

un poco más de una escritura here


Terminé usando un hipervínculo normal junto con Url.Action , como en:

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

Es más feo, pero tienes un poco más de control sobre la etiqueta a, que a veces es útil en sitios fuertemente AJAXified.

HTH


Actualización: MVC 3 y las versiones más recientes tienen soporte incorporado para esto. Vea la respuesta altamente actualizada de JohnnyO a continuación para obtener las soluciones recomendadas.

No creo que haya ayudantes inmediatos para lograr esto, pero tengo dos ideas para que pruebes:

// 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" ) )%>

Solo ideas, no lo he probado.







custom-data-attribute