2010-03-26 16 views
302

Estoy intentando usar HTML5 data- attributes en mi proyecto ASP.NET MVC 1. (Soy un novato C# y ASP.NET MVC.)Cómo usar guiones en los atributos HTML-5 data- * en 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 las anteriores htmlAttributes dar 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 "datos-" según la especificación.

Mis preguntas:

  • ¿Hay alguna manera de conseguir este trabajo y utilizar datos HTML5 atributos con Html.ActionLink o ayudantes HTML similares?
  • ¿Hay algún otro mecanismo alternativo para adjuntar datos personalizados a un elemento? Esta información será procesada posteriormente por JS.
+4

esto es una vieja pregunta con respuesta obsoleta - usuarios de MVC 3 y superior deben ver esta cuestión http://stackoverflow.com/questions/2897733/hyphenated-html-attributes-with-asp-net-mvc –

Respuesta

105

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

no creo que hay algún ayudantes inmediatos para lograr esto, pero tengo dos ideas para que usted intente:

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

sólo ideas, no lo he probado.

+5

Hola. Si desea utilizar el primer enfoque, simplemente asegúrese de que su diccionario sea del tipo Diccionario . –

+39

Si bien esto funciona técnicamente, la forma recomendada (comenzando con MVC 3) es utilizar un guión bajo en lugar del guión (como señaló JohnnyO). –

+3

¡Confundir al mundo entero con esta respuesta * elegida hasta * notar la verdadera respuesta anterior! –

3

Terminé usando un hipervínculo normal a lo largo de 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 usted tiene un poco más de control sobre la etiqueta a, que a veces es útil en sitios muy Ajaxified .

HTH

0

no me gusta el uso puro "una" etiqueta, el exceso de escribir. Entonces vengo con la solución. En vista de que se vea

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

Implementación de la 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)); 
    } 
} 
+1

Seguramente hay un mejor nombre de clase ... ¡un 't' extra al final al menos! – hvaughan3

601

Este problema se ha abordado en ASP.Net MVC 3. Ahora se transforman automáticamente guiones en html atribuyen propiedades de guiones. Tuvieron suerte en este caso, ya que los guiones bajos no son legales en los atributos html, por lo que MVC puede implicar con confianza que le gustaría un guión cuando usa un guión bajo.

Por ejemplo:

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

hará que esto en MVC 3:

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

Si usted todavía está utilizando una versión anterior de MVC, puede imitar lo MVC 3 está haciendo mediante la creación de este método estático que me prestó el 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 se puede utilizar de esta manera:

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

y esto hará que el Data- correcta * atributo:

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

Esto no funciona para mí por alguna razón. La fuente de vista muestra data_ *. Usando MVC3. ¿Algunas ideas? –

+0

Hola Simon, ¿resolviste tu problema? Si no, ¿puede proporcionar el código que le causa el problema? –

+18

+++ 1, esto debería marcarse como la respuesta correcta ahora –

4

se puede implementar esta con una nueva función de extensión de ayuda HTML que luego se utiliza de manera similar a los existentes ActionLinks.

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 :-)

edición

poco más de un escribir here

57

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 del 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 lo mencionó.

+12

El método responsable de esto es: HtmlHel per.AnonymousObjectToHtmlAttributes (object), en caso de que alguien se pregunte por qué su extensión personalizada no reemplazará el guión bajo con un guión. – Nikkelmann

+1

Esto realmente necesita votar, ya que es la respuesta más simple y funciona perfectamente. –

-3

Se puede utilizar la siguiente manera:

En MVC:

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

en HTML:

<input type="text" name="Id" data_val_number="10"/> 
14

En MVC 4 podría traducirse con el guión bajo (" _ ")

Razor:

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

HTML representada

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

hola, ¿hay alguna manera de PUBLICAR el archivo de datos al controlador, a través de un Ajax o enviar. preguntándose cómo aprovechar los datos. Por ejemplo, si tuviera una 'data-date' en el atributo, ¿cómo podría publicarlo en el controlador/acción? Además, ¿qué es% 23 allí? – transformer

+0

Sí, use la colección de formularios y acceda a ella con ID o Nombre, y% 23 es # – mzonerz

Cuestiones relacionadas