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

Resuelto Shameem asked hace 14 años • 8 respuestas

Estoy intentando utilizar atributos de datos HTML5 en mi proyecto ASP.NET MVC 1. (Soy un novato en 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 "detalles de datos" en los atributos htmlAttributes 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 forma de hacer que esto funcione y utilizar atributos de datos HTML5 con Html.ActionLink o ayudantes HTML similares?
  • ¿Existe algún otro mecanismo alternativo para adjuntar datos personalizados a un elemento? Estos datos serán procesados ​​posteriormente por JS.
Shameem avatar Mar 26 '10 07:03 Shameem
Aceptado

Este problema se solucionó en ASP.Net MVC 3. Ahora convierten automáticamente los guiones bajos en las propiedades de los atributos html en guiones. Tuvieron suerte con este caso, ya que los guiones bajos no son legales en los atributos html, por lo que MVC puede implicar con confianza que desea un guión cuando usa un guión bajo.

Por ejemplo:

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

representará esto en MVC 3:

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

Si todavía estás usando una versión anterior de MVC, puedes imitar lo que hace MVC 3 creando este método estático que tomé prestado del código fuente de MVC3:

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

Y luego puedes usarlo así:

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

y esto generará el atributo data-* correcto:

<input data-bind="foo" id="City" name="City" type="text" value="" />
Johnny Oshika avatar Dec 23 '2010 01:12 Johnny Oshika

Actualización: MVC 3 y versiones más recientes tienen soporte integrado para esto. Consulte la respuesta altamente votada de JohnnyO a continuación para conocer las soluciones recomendadas.

No creo que exista ninguna ayuda inmediata para lograrlo, 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.

Morten Mertner avatar Mar 26 '2010 01:03 Morten Mertner