MvcHtmlString là gì và khi nào tôi nên sử dụng nó?


221

Các tài liệu cho MvcHtmlStringkhông phải là khai sáng khủng khiếp:

Đại diện cho một chuỗi được mã hóa HTML không nên được mã hóa lại.

Tôi không rõ chính xác ý nghĩa của việc này là gì. Có vẻ như một số phương thức của trình trợ giúp HTML trả về một MvcHtmlString, nhưng một số ví dụ tôi đã thấy trực tuyến về các trình trợ giúp tùy chỉnh chỉ trả về một chuỗi thông thường.

Câu hỏi:

Một là MvcHtmlStringgì?

Khi nào tôi nên chọn MvcHtmlStringhơn stringvà ngược lại? Tại sao?

Câu trả lời:


246

ASP.NET 4 giới thiệu một cú pháp mã nugget mới <%: %>. Về cơ bản, <%: foo %>dịch sang <%= HttpUtility.HtmlEncode(foo) %>. Nhóm đang cố gắng để các nhà phát triển sử dụng <%: %>thay vì <%= %>bất cứ nơi nào có thể để ngăn chặn XSS.

Tuy nhiên, điều này đưa ra một vấn đề là nếu một mã nugget đã mã hóa kết quả của nó, <%: %>cú pháp sẽ mã hóa lại nó. Điều này được giải quyết bằng cách giới thiệu giao diện IHtmlString (mới trong .NET 4). Nếu foo () trong <%: foo() %>lợi nhuận một IHtmlString, các <%: %>cú pháp sẽ không nó re-encode.

Trình trợ giúp của MVC 2 trả về MvcHtmlString, trên ASP.NET 4 thực hiện giao diện IHtmlString. Do đó, khi các nhà phát triển sử dụng <%: Html.*() %>trong ASP.NET 4, kết quả sẽ không được mã hóa kép.

Biên tập:

Một lợi ích ngay lập tức của cú pháp mới này là quan điểm của bạn sạch sẽ hơn một chút. Ví dụ, bạn có thể viết <%: ViewData["anything"] %>thay vì <%= Html.Encode(ViewData["anything"]) %>.


Tôi muốn thêm rằng MVC 2 được biên dịch dựa trên .Net 3.5, không phải 4. Điều này có nghĩa là MvcHtmlStringkhông triển khai IHtmlStringvì nó chỉ tồn tại trong 4. <%:Cú pháp phải kiểu vịt - nó sẽ luôn gọi .ToHtmlString()trước .ToString()bất kể giao diện.
Keith

2
Tôi đã sửa chữa - thực sự MvcHtmlString.Createphương thức phát hiện xem IHtmlStringcó sẵn hay không và tự động tạo lớp trả về để hỗ trợ nó nếu đó là: windowsitpro.com/article/net-framework/Encoding-and-Strings/iêu
Keith

Theo dõi: Có sự khác biệt có ý nghĩa giữa MvcHtmlString và HtmlString không? Sau khi đọc các tài liệu được liên kết ở trên, tôi vẫn không biết MvcHtmlString mang đến cho tôi điều gì mà HtmlString không có.
flipdoubt

@flipdoubt - Không có sự khác biệt có ý nghĩa.
Levi

2
Có một sự khác biệt rất nhỏ giữa hai. MvcHtmlString sẽ trả về String.Empty trong ToString () hoặc ToHtmlString () nếu bạn truyền cho nó một chuỗi null. HtmlString sẽ tiếp tục trả về null, mặc dù.
tái lập

87

Đây là một câu trả lời muộn nhưng nếu bất cứ ai đọc câu hỏi này đang sử dụng dao cạo, điều bạn nên nhớ là dao cạo mã hóa mọi thứ theo mặc định, nhưng bằng cách sử dụng MvcHtmlStringtrong trình trợ giúp html của bạn, bạn có thể nói với dao cạo rằng nó không cần mã hóa nó .

Nếu bạn muốn dao cạo không mã hóa chuỗi, hãy sử dụng

@Html.Raw("<span>hi</span>")

Dịch ngược Raw (), cho chúng ta thấy rằng nó đang quấn chuỗi trong HtmlString

public IHtmlString Raw(string value) {
    return new HtmlString(value); 
}

" HtmlString chỉ tồn tại trong ASP.NET 4.

MvcHtmlString là một shim tương thích được thêm vào MVC 2 để hỗ trợ cả .NET 3.5 và .NET 4. Bây giờ, MVC 3 chỉ là .NET 4, đó là một lớp con khá tầm thường của HtmlString có lẽ dành cho MVC 2-> 3 để tương thích nguồn. " nguồn


11

Một cách sử dụng thực tế tuyệt vời này là nếu bạn muốn tạo các HtmlHelpertiện ích mở rộng của riêng mình . Ví dụ: tôi ghét cố gắng nhớ <link>cú pháp thẻ, vì vậy tôi đã tạo phương thức tiện ích mở rộng của riêng mình để tạo <link>thẻ:

<Extension()> _
Public Function CssBlock(ByVal html As HtmlHelper, ByVal src As String, ByVal Optional ByVal htmlAttributes As Object = Nothing) As MvcHtmlString
    Dim tag = New TagBuilder("link")
    tag.MergeAttribute("type", "text/css")
    tag.MergeAttribute("rel", "stylesheet")
    tag.MergeAttribute("href", src)
    tag.MergeAttributes(New RouteValueDictionary(htmlAttributes))
    Dim result = tag.ToString(TagRenderMode.Normal)
    Return MvcHtmlString.Create(result)
End Function

Tôi có thể đã quay trở lại Stringtừ phương thức này, nhưng nếu tôi có những điều sau đây sẽ bị phá vỡ:

<%: Html.CssBlock(Url.Content("~/sytles/mysite.css")) %>

Với MvcHtmlString, sử dụng một trong hai <%: ... %>hoặc <%= ... %>sẽ hoạt động chính xác.


7

Bạn sẽ sử dụng MvcHtmlStringnếu bạn muốn truyền HTML thô cho phương thức trình trợ giúp MVC và bạn không muốn phương thức trình trợ giúp mã hóa HTML.


Hmm ... Tôi nghĩ rằng toàn bộ quan điểm của một phương thức trợ giúp HTML là mã hóa HTML. Tôi sẽ làm gì khác với phương thức trợ giúp HTML?
devuxer

Và, bên cạnh đó, khi sẽ Tôi muốn trở lại một MvcHtmlStringtừ một phương pháp helper HTML?
devuxer

Vượt qua hoặc trở về từ. Bạn sẽ muốn trả lại một cái nếu trình trợ giúp HTML của bạn tạo HTML thoát trước và bạn không muốn bất kỳ ai thoát khỏi nó.
SLaks

1
Được rồi, tôi nghĩ rằng điều đó giúp tôi gần hơn một chút, nhưng (có nguy cơ gặp phải một người thông minh) làm thế nào để tôi quyết định liệu tôi có muốn ai khác thoát khỏi nó không? Có phải nói chung là thực hành tốt / xấu để cung cấp cho ai đó khả năng gây rối với html đã thoát? Tôi chưa bao giờ thấy một cấu trúc như thế này trước đây. "Nó giống như một chuỗi, nhưng xin đừng chạm vào nó ... không phải là có bất cứ điều gì ngăn cản bạn chạm vào nó, nhưng chúng tôi muốn bạn không nên." Đó là những gì về?
devuxer

1
Vấn đề là rằng không giống như một chuỗi bình thường, này chuỗi đã được mã hóa. Do đó, không cần phải chạm vào nó.
SLaks
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.