2010-03-26 40 views
302

Tôi đang cố sử dụng HTML5 data- attributes trong dự án ASP.NET MVC 1 của mình. (Tôi là một C# và ASP.NET MVC newbie.)Cách sử dụng dấu gạch ngang trong thuộc tính data-* HTML trong ASP.NET MVC

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

Các "dữ liệu chi tiết" trong htmlAttributes trên cung cấp cho các lỗi sau:

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

Nó hoạt động khi tôi sử dụng data_details, nhưng Tôi đoán nó cần phải được bắt đầu với "data-" theo spec.

Câu hỏi của tôi:

  • Có cách nào để làm việc này và sử dụng HTML5 dữ liệu thuộc tính với Html.ActionLink hoặc những người giúp đỡ Html tương tự?
  • Có cơ chế thay thế nào khác để đính kèm dữ liệu tùy chỉnh vào một phần tử không? Dữ liệu này sẽ được JS xử lý sau.
+4

đây là một câu hỏi cũ với câu trả lời lạc hậu - những người sử dụng MVC 3 trở lên nên xem câu hỏi này http://stackoverflow.com/questions/2897733/hyphenated-html-attributes-với-asp-net-mvc –

Trả lời

105

Cập nhật: MVC 3 và các phiên bản mới hơn có hỗ trợ tích hợp cho điều này. Xem câu trả lời được đánh giá cao của JohnnyO bên dưới để biết các giải pháp được đề xuất.

Tôi không nghĩ có bất kỳ người giúp đỡ ngay lập tức để đạt được điều này, nhưng tôi có hai ý tưởng để bạn có thể thử:

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

Chỉ cần ý tưởng, đã không kiểm tra nó.

+5

Xin chào. Nếu bạn muốn sử dụng cách tiếp cận thứ nhất, chỉ cần đảm bảo rằng từ điển của bạn là kiểu Dictionary . –

+39

Trong khi kỹ thuật này hoạt động, cách được khuyến nghị (bắt đầu với MVC 3) là sử dụng dấu gạch dưới thay cho dấu nối (như JohnnyO đã chỉ ra). –

+3

Lẫn lộn cả thế giới với câu trả lời đã chọn này * cho đến khi * nhận thấy câu trả lời thực sự ở trên! –

3

tôi đã kết thúc bằng một siêu liên kết bình thường cùng với Url.Action, như trong:

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

Đó là xấu xí, nhưng bạn đã có một chút kiểm soát nhiều hơn thẻ a, mà đôi khi hữu ích trong các trang web nặng nề AJAXified .

HTH

0

Tôi không thích sử dụng thẻ "a" thuần túy, quá nhiều đánh máy. Vì vậy, tôi đi kèm với giải pháp. Theo quan điểm của nó trông

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

Thực hiện lớp 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

Chắc chắn có một tên lớp tốt hơn ... thêm 't' vào cuối ít nhất! – hvaughan3

601

Vấn đề này đã được giải quyết trong ASP.Net MVC 3. Bây giờ họ tự động chuyển đổi dấu gạch trong html tính để dấu gạch ngang thuộc tính. Họ đã may mắn về điều này, vì dấu gạch dưới không hợp pháp trong thuộc tính html, vì vậy MVC có thể tự tin ngụ ý rằng bạn muốn một dấu gạch ngang khi bạn sử dụng dấu gạch dưới.

Ví dụ:

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

sẽ làm cho này trong MVC 3:

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

Nếu bạn vẫn đang sử dụng một phiên bản cũ của MVC, bạn có thể bắt chước những gì MVC 3 được làm bằng cách tạo phương pháp tĩnh này mà tôi mượn từ mã nguồn của 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; 
    } 
} 

Và sau đó bạn có thể sử dụng nó như sau:

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

và điều này sẽ làm cho đĩa dữ liệu đúng * thuộc tính:

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

Điều này không hiệu quả đối với tôi vì một số lý do. Xem nguồn hiển thị dữ liệu_ *. Sử dụng MVC3. Bất kỳ ý tưởng? –

+0

Xin chào Simon, bạn đã giải quyết được vấn đề của mình chưa? Nếu không, bạn có thể cung cấp mã của mình gây ra sự cố không? –

+18

+++ 1, điều này phải được đánh dấu là câu trả lời chính xác ngay bây giờ –

4

Bạn có thể thực hiện điều này với một chức năng mở rộng helper Html mới mà sau đó sẽ được sử dụng tương tự như ActionLinks hiện có.

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

Và bạn gọi nó như vậy ...

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

Simples :-)

chỉnh sửa hơn

chút của một ghi lên here

57

Đó là thậm chí còn dễ hơn mọi thứ được đề xuất ở trên. Thuộc tính dữ liệu trong MVC bao gồm dấu gạch ngang (-) được phục vụ cho việc sử dụng dấu gạch dưới (_).

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

Tôi thấy JohnnyO đã đề cập đến điều này.

+12

Phương thức chịu trách nhiệm cho điều này là: HtmlHel per.AnonymousObjectToHtmlAttributes (đối tượng), trong trường hợp bất kỳ ai tự hỏi tại sao tiện ích tùy chỉnh của họ sẽ không thay thế gạch dưới bằng dấu gạch nối. – Nikkelmann

+1

Điều này thực sự cần phải bỏ phiếu vì nó là câu trả lời đơn giản nhất và hoạt động hoàn hảo! –

-3

Bạn có thể sử dụng nó như thế này:

Trong MVC:

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

Trong Html:

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

Trong MVC 4 có thể được trả lại với dấu gạch dưới (" _ ")

Razor:

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

rendered Html

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

hi, là có một cách để POST dữ liệu-fid để điều khiển, thông qua một Ajax hoặc gửi. tự hỏi làm thế nào để tận dụng dữ liệu. Ví dụ: nếu tôi có 'ngày dữ liệu' trong thuộc tính, Làm thế nào tôi có thể đăng nó lên bộ điều khiển/hành động? Ngoài ra% 23 có – transformer

+0

Có sử dụng bộ sưu tập biểu mẫu và truy cập nó với ID hoặc Tên và% 23 là # – mzonerz

Các vấn đề liên quan