ASP.NET MVC'de HTML-5 data- * özniteliklerinde tire nasıl kullanılır


325

ASP.NET MVC 1 projemde HTML5 veri özniteliklerini kullanmaya çalışıyorum . (Ben bir C # ve ASP.NET MVC acemi.)

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

Yukarıdaki htmlAttributes içindeki "veri ayrıntıları" aşağıdaki hatayı verir:

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

Ben data_details kullandığımda çalışır, ama şartname başına "data-" ile başlaması gerekiyor sanırım.

Sorularım:

  • Bu çalışmanın ve HTML5 veri özniteliklerini Html.ActionLink veya benzer Html yardımcılarıyla kullanmanın herhangi bir yolu var mı?
  • Bir öğeye özel veri eklemek için başka bir alternatif mekanizma var mı? Bu veriler daha sonra JS tarafından işlenecektir.

5
bu eski cevabı olan eski bir sorudur - MVC 3 ve üstü kullanıcılar bu soruyu görüntülemelidir stackoverflow.com/questions/2897733/…
ED-209

Yanıtlar:


115

Güncelleme: MVC 3 ve daha yeni sürümler bunun için yerleşik desteğe sahiptir. Önerilen çözümler için JohnnyO'nun son derece yükseltilmiş cevabına bakın.

Bunu başarmak için acil bir yardımcı olduğunu düşünmüyorum, ancak denemeniz için iki fikrim var:

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

Sadece fikirler, test etmedim.


5
Selam. 1. yaklaşımı kullanmak istiyorsanız, sözlüğünüzün Dictionary <String, Object> türünde olduğundan emin olun.
Ondrej Stastny

40
Bu teknik olarak çalışırken, önerilen yol (MVC 3 ile başlayan) tire yerine bir alt çizgi kullanmaktır (JohnnyO'nun işaret ettiği gibi).
Curtis,

3
Yukarıdaki gerçek cevabı fark edene kadar tüm dünyayı bu seçilen cevapla karıştırmak !
Rubens Mariuzzo

648

Bu sorun ASP.Net MVC 3'te giderilmiştir. Artık html öznitelik özelliklerindeki alt çizgileri otomatik olarak tirelara dönüştürmektedirler. Alt çizgiler html özelliklerinde yasal olmadığından, bu konuda şanslı oldular, bu nedenle MVC, bir alt çizgi kullandığınızda güvenle bir çizgi istediğinizi ima edebilir.

Örneğin:

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

MVC 3'te bunu gerçekleştirecek:

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

Hala MVC'nin eski bir sürümünü kullanıyorsanız, MVC3'ün kaynak kodundan ödünç aldığım bu statik yöntemi oluşturarak MVC 3'ün ne yaptığını taklit edebilirsiniz:

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

Ve sonra şöyle kullanabilirsiniz:

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

ve bu doğru data- * özniteliğini oluşturur:

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

6
Bu benim için bir sebepten dolayı işe yaramıyor. Kaynağı görüntüle veriyi gösterir *. MVC3 kullanma. Herhangi bir fikir?
Simon Hartcher

Merhaba Simon, sorununu çözdün mü? Değilse, soruna neden olan kodunuzu sağlayabilir misiniz?
Johnny Oshika

Hala şans yok WebGrid.GetHtml(htmlAttributes: new { data_some : "thing" }). : '(
Rubens Mariuzzo

Alt çizgilerin neden işe yarayacağını belirtmek için +1. HTML için özellik adlarında alt çizgilerin geçerli olmadığı bana gelmedi!
Umar Farooq Khawaja

2
@RubensMariuzzo Bu, RouteValueDictionaryMVC3'ün Html.Something()yöntemlerine değil. O bu mümkün WebGridaynı şekilde yükseltilmemişse veya üzerinde versiyonunu kontrol edebilirSystem.Web.Helpers.dll
Keith

58

Yukarıda önerilenden daha da kolay. MVC'de tire (-) içeren veri öznitelikleri, alt çizgi (_) kullanılarak sunulur.

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

Görüyorum ki JohnnyO bundan daha önce bahsetti.


12
Bundan sorumlu yöntem şudur: HtmlHelper.AnonymousObjectToHtmlAttributes (object), herhangi birinin özel uzantısının neden alt çizgiyi bir tire ile değiştirmeyeceğini merak etmesi durumunda.
Nikkelmann

1
Bu, şimdiye kadar en basit cevap olduğu ve mükemmel çalıştığı için oy vermek gerekiyor!
Dan Diplo

21

In mvc 4 Alt çizgi ile oluşturulabilir ("_")

Ustura:

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

Oluşturulan Html

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

merhaba, bir Ajax veya gönderme yoluyla kontrolöre veri akışını POST bir yolu var mı. verileri nasıl kullanacağınızı merak ediyorum. Örneğin data-date, öznitelikte bir varsa , denetleyiciye / eyleme nasıl gönderebilirim? Ayrıca orada% 23 nedir
transformatör

Evet, form toplamayı kullanın ve kimlik veya Ad ile erişin ve% 23 #
mzonerz

4

Bunu, daha sonra mevcut ActionLinks'e benzer şekilde kullanılacak yeni bir Html yardımcı uzantısı işleviyle uygulayabilirsiniz.

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

Ve öyle diyorsun ...

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

Basit :-)

Düzenle

burada biraz daha fazla yazı var


3

İle birlikte, normal bir köprü kullanarak sona erdi Url.Action:

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

Daha çirkin, ancak aetiket üzerinde biraz daha fazla kontrole sahipsiniz , bu da bazen yoğun AJAXified sitelerinde faydalıdır.

HTH


0

Saf "a" etiketi kullanmayı sevmiyorum, çok fazla yazıyorum. Ben de çözüm ile geliyorum. Görünüşe göre

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

Dic sınıfının uygulanması

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
Kesinlikle daha iyi bir sınıf adı var ... ten azından sonunda ekstra !
hvaughan3

-2

Bu şekilde kullanabilirsiniz:

Mvc dilinde:

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

Html'de:

<input type="text" name="Id" data_val_number="10"/>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.