2015-09-05 32 views
14

Dường như với tôi rằng có những thay đổi đột phá lớn trong TagBuilder như của beta7 mà không đề cập đến chúng trong repo thông báo.TagBuilder InnerHtml trong ASP.NET 5 MVC 6

Cụ thể. ToString không còn hiển thị trình tạo thẻ, nó chỉ trả về tên của loại. trước đây chúng ta có thể làm những việc như thế này trong phần mở rộng HtmlHelper của chúng tôi để xây dựng các yếu tố html lồng nhau:

var li = new TagBuilder("li"); 
li.AddCssClass("inactive"); 
var span = new TagBuilder("span"); 
span.SetInnerText(somestring); 
li.InnerHtml = span.ToString(); 

.InnerHtml bây giờ không còn chấp nhận chuỗi vì nó bây giờ là IHtmlContent

nhưng vì ToString() doesn' t hiển thị thẻ này không hoạt động:

li.InnerHtml = new HtmlString(span.ToString()) 

nó chỉ hiển thị là "Microsoft.AspNet.Mvc.Rendering.TagBuilder", tên của loại.

Tôi không thấy bất kỳ phương pháp mới nào trên TagBuilder để cung cấp chức năng cần thiết. Tôi đang thiếu gì? Làm thế nào tôi có thể xây dựng html lồng nhau phức tạp với TagBuilder bây giờ?

+0

'TagBuilder' triển khai' IHtmlContent' vì vậy có lẽ bạn chỉ có thể chỉ định Trình tạo thẻ trực tiếp cho 'li.InnerHtml'? – fiat

Trả lời

13

TagBuilder hiện đang triển khai IHtmlContent, bạn sẽ có thể sử dụng trực tiếp mà không cần thực hiện .ToString().

var li = new TagBuilder("li"); 
li.AddCssClass("inactive"); 
var span = new TagBuilder("span"); 
span.SetInnerText(somestring); 
li.InnerHtml = span; 

Vấn đề thực sự với việc thực hiện hiện nay ở Beta 7 là không có cách nào dễ dàng để thêm hai nội dung thẻ con người xây dựng cho phụ huynh một. Bạn có thể theo dõi cuộc thảo luận trên GitHub.

Đề xuất hiện tại là tạo InnerHtml không thể chuyển nhượng được, nhưng thay vào đó hãy hỗ trợ Append. Đây là mục tiêu được triển khai trong Beta 8.

Cách giải quyết trong Beta 7 là để gọi parent.WriteTo với một StringWriter để chuyển nó sang một string.

+2

Tôi đã nói vấn đề thực sự là số lượng lớn mã MVC3 + đã sử dụng 'TagBuilder.ToString()' trong các phương thức 'HtmlHelper' tùy chỉnh và bây giờ đã hoàn toàn bị hỏng. Có phải đó là cấp tiến để muốn có được một chuỗi HTML ra khỏi một lớp học, er, xây dựng chuỗi HTML? – Sam

+3

MVC 6 là một con thú hoàn toàn khác với MVC 5 và trước đó. Khả năng tương thích ngược không bao giờ là ưu tiên. Sự khác biệt có thể so sánh với sự khác biệt giữa WebForms và MVC (lớn hơn cường điệu - tôi biết). Bạn sẽ không thấy nhiều dự án được di chuyển. MVC 6 được nhắm mục tiêu nhiều hơn cho các dự án mới và làm lại hoàn chỉnh. –

+2

Tôi đánh giá cao điều này, nhưng tôi nghi ngờ rằng nhiều người trong số những người này https://github.com/search?l=csharp&q=TagBuilder+HtmlHelper&type=Code&utf8=✓ sẽ nhận được một cú sốc thô lỗ khi họ di chuyển mã thành phần có thể sử dụng lại và âm thầm thất bại trên chúng. Việc thực thi 'ToString()' đó vi phạm Nguyên tắc Ít ngạc nhiên nhất và làm cho việc di cư khó khăn hơn nhiều, vì không có lý do chính đáng (ngoài “Chúng tôi nghĩ mọi người không nên làm điều này”). – Sam

2

Beta 8 giải quyết vấn đề này bằng cách thêm phương thức Append() để gắn thẻ người trợ giúp.

Đối với phiên bản beta 7, giải pháp sẽ là sử dụng lớp BufferedHtmlContent(), nhưng vì không thể truy cập nên chúng tôi phải thực hiện thêm một số công việc.

private class MyBufferedHtmlContent : IHtmlContent 
{ 
    internal List<IHtmlContent> Entries { get; } = new List<IHtmlContent>(); 

    public MyBufferedHtmlContent Append(IHtmlContent htmlContent) 
    { 
     Entries.Add(htmlContent); 
     return this; 
    } 

    public void WriteTo(TextWriter writer, IHtmlEncoder encoder) 
    { 
     foreach (var entry in Entries) 
     { 
      entry.WriteTo(writer, encoder); 
     } 
    } 
} 

Cách sử dụng:

TagBuilder firstChild = new TagBuilder("input"); 
firstChild.MergeAttribute("type", "hidden"); 
firstChild.MergeAttribute("name", "Ids"); 
firstChild.TagRenderMode = TagRenderMode.SelfClosing; 

TagBuilder secondChild = new TagBuilder("input"); 
secondChild.MergeAttribute("type", "hidden"); 
secondChild.MergeAttribute("name", "Ids"); 
secondChild.TagRenderMode = TagRenderMode.SelfClosing; 

var innerHtml = new MyBufferedHtmlContent(); 
innerHtml.Append(firstChild); 
innerHtml.Append(secondChild); 
TagBuilder parent = new TagBuilder("div"); 
parent.InnerHtml = innerHtml; 
+0

http://imgur.com/L0neS57 ... InnerHtml không có thiết lập ... – Jack

+0

Kiểm tra phiên bản beta của bạn. Đây là phiên bản beta 7. –

12

Sử dụng MVC 6, tại thời điểm viết bài, Tagbuiler.InnerHtml thực sự không có setter nữa. Nó có một số phương pháp thay thế để nối thêm phần tử. Ví dụ bạn có thể viết:

var container = new TagBuilder("div"); 
var input = new TagBuilder("input"); 

container.InnerHtml.AppendHtml(input); 
2

@Memet Olsen

Tất cả TagHelpers tùy chỉnh của tôi đã phá vỡ với một cập nhật cho 4.6.1 (1.0.0-RC2). InnerHtml.Append() sẽ không còn chấp nhận Trình tạo thẻ.

Thay vào đó, phương pháp AppendHtml() nên được sử dụng:

var container = new TagBuilder("div"); 
var input = new TagBuilder("input"); 

container.InnerHtml.AppendHtml(input); 

2 lỗi-sửa chữa [here]

1

xây dựng trên @ câu trả lời Mihai để hiển thị các mã thực tế cho cách tiếp cận StringWriter:

// Create tag builder 
var builder = new TagBuilder("img"); 
//... 
// Render tag approach also changed in .NetCore 
builder.TagRenderMode = TagRenderMode.SelfClosing; 

//Create the StringWriter and make TagBuilder "WriteTo" it 
var stringWriter = new System.IO.StringWriter(); 
builder.WriteTo(stringWriter, HtmlEncoder.Default); 
var tagBuilderIsFinallyAStringNow = stringWriter.ToString(); 
0

Mất span.SetInnerText(somestring); hiện tại có thể thực hiện

span.InnerHtml.SetContent(somestring);

sử dụng Microsoft.AspNetCore.Html.HtmlContentBuilderExtensions.

Điều này đến từ góc độ 4.7 với AspNetCore 2.0.1.

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