Cách sử dụng dấu gạch ngang trong các thuộc tính dữ liệu HTML-5 trong ASP.NET MVC


325

Tôi đang cố gắng sử dụng các thuộc tính dữ liệu HTML5 trong dự án ASP.NET MVC 1 của mình. (Tôi là người mới sử dụng C # và ASP.NET MVC.)

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

"Chi tiết dữ liệu" trong htmlAttribution ở trên đưa ra 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 bắt đầu bằng "data-" theo thông số kỹ thuật.

Những câu hỏi của tôi:

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

5
đây là một câu hỏi cũ với câu trả lời đã lỗi thời - người dùng MVC 3 trở lên nên xem câu hỏi này stackoverflow.com/questions/2897733/ chủ đề
ED-209

Câu trả lời:


115

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 việc 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 trợ giúp ngay lập tức nào để đạt được điều này, nhưng tôi có hai ý tưởng để bạn 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ỉ là ý tưởng, chưa thử nghiệm nó.


5
Chào. Nếu bạn muốn sử dụng cách tiếp cận thứ 1, chỉ cần đảm bảo rằng từ điển của bạn thuộc loại Từ điển <Chuỗi, Đối tượng>.
Ondrej Stastny

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

3
Nhầm lẫn cả thế giới với câu trả lời được chọn này cho đến khi nhận thấy câu trả lời thực sự ở trên!
Rubens Mariuzzo

648

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 dưới trong thuộc tính html thành dấu gạch ngang. Họ đã gặp may mắn với điều này, vì dấu gạch dưới không hợp pháp trong các thuộc tính html, do đó, MVC có thể tự tin ám chỉ rằng bạn thích 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ẽ kết xuất cái 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 phiên bản cũ hơn của MVC, bạn có thể bắt chước những gì MVC 3 đang làm bằng cách tạo phương thức 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ư thế này:

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

và điều này sẽ khiến thuộc tính data- * chính xác:

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

6
Điều này không làm việc cho tôi vì một số lý do. Xem nguồn hiển thị dữ liệu_ *. Sử dụng MVC3. Có ý kiến ​​gì không?
Simon Hartcher

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

Vẫn không có may mắn với WebGrid.GetHtml(htmlAttributes: new { data_some : "thing" }). : '(
Rubens Mariuzzo

+1 để chỉ định lý do tại sao dấu gạch dưới sẽ hoạt động. Nó đã không xảy ra với tôi rằng dấu gạch dưới không hợp lệ trong tên thuộc tính cho HTML!
Umar Farooq Khawaja

2
@RubensMariuzzo điều này không được áp dụng cho các phương thức RouteValueDictionarycủa MVC3 Html.Something(). Có thể WebGridchưa được nâng cấp theo cùng một cách hoặc bạn có thể kiểm tra phiên bản trênSystem.Web.Helpers.dll
Keith

58

Nó thậm chí còn dễ dàng hơn mọi thứ được đề xuất ở trên. Các 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 việc này là: HtmlHelper.AnonymousObjectToHtmlAttribut (object), trong trường hợp bất kỳ ai cũng thắc mắc tại sao tiện ích mở rộng tùy chỉnh của họ sẽ không thay thế dấu gạch dưới bằng dấu gạch nối.
Nikkelmann

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

21

Trong mvc 4 có thể được hiển thị bằng Underscore ("_")

Dao cạo:

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

Kết xuất Html

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

xin chào, có cách nào để POST dữ liệu-fid cho bộ điều khiển, thông qua 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ó một data-datethuộ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 ở đó là bao nhiêu
máy biến áp

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

4

Bạn có thể thực hiện điều này với chức năng mở rộng trình trợ giúp Html mới, sau đó sẽ được sử dụng tương tự như các ActionLink 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" })  %>

Đơn giản :-)

biên tập

thêm một chút viết lên đây


3

Tôi đã kết thúc bằng cách sử dụ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>

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

HTH


0

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

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

Triển khai 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 ... tít nhất là thêm vào cuối!
hvaughan3

-2

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"/>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.