2010-08-11 9 views
67

Tôi có một số nghi ngờ về cách nối các trường hợp MvcHtmlString vì thông tin này được tìm thấy trong MSDN:Làm thế nào để nối một số trường hợp MvcHtmlString

MvcHtmlString Lớp Đại diện cho một chuỗi HTML mã hóa mà không nên mã hóa một lần nữa

tôi có nguy cơ rằng chuỗi được HTML mã hóa hai lần khi sử dụng mã như thế này:

var label = Html.LabelFor(model => model.Email); 
var textbox = Html.TextBoxFor(model => model.Email); 
var validation = Html.ValidationMessageFor(model => model.Email); 

var result = MvcHtmlString.Create(
    label.ToString() + textbox.ToString() + validation.ToString()); 

(lưu ý: đây là nghĩa vụ phải đi vào một phương pháp mở rộng HtmlHelper để giảm trùng lặp mã trong dạng xem).

Trả lời

26

Mã của bạn là chính xác.

Đoạn mã từ MSDN có nghĩa là Công cụ xem mã hóa (chẳng hạn như công cụ xem Aspx trong .NET 4 khi sử dụng <%: %> hoặc công cụ xem Dao cạo trong MVC 3) không được mã hóa lại giá trị chuỗi của đối tượng.

Vì vậy, ví dụ:

string s = "<tag>"; 
var hs = MvcHtmlString.Create(s); 

<%: s %> -- outputs "&lt;tag&gt;" 
<%: hs %> -- outputs "<tag>" 
57

Quá xấu C# sẽ không cho phép chúng tôi ghi đè lên các nhà điều hành + ở đây! Làm thế nào về việc sử dụng một phương pháp mở rộng thay thế?

public static MvcHtmlString Concat(this MvcHtmlString first, params MvcHtmlString[] strings) 
{ 
    return MvcHtmlString.Create(first.ToString() + string.Concat(strings.Select(s => s.ToString()))); 
} 

Điều này có thể được tối ưu hóa, nhưng bạn có thể chạy với nó. Nó nên được khá tầm thường để chứng minh rằng điều này không tăng gấp đôi chuỗi mã hóa với một bài kiểm tra đơn vị.

mẫu Cách sử dụng:

label.Concat(textbox, validation) 

Và bây giờ là một plug shameless cho blog của tôi: Use TagBuilder or HtmlTags to clean up your HTML

+2

này không biên dịch đối với tôi, tôi đã thay đổi nó: \t public static MvcHtmlString concat (MvcHtmlString này đầu tiên, params MvcHtmlString [] strings) \t { \t \t trả về MvcHtmlString.Create (first.ToString() + string.Concat (strings.Select (s => s.ToString()). ToArray())); \t} – Charlie

+0

có lý do khiến thông số đầu vào không phải là 'IHtmlString' không? – Maslow

+1

IHtmlString không tồn tại.NET 3.5 – Ryan

19

tôi đã đi cho cách tiếp cận này:

private static MvcHtmlString Concat(params MvcHtmlString[] items) 
    { 
     var sb = new StringBuilder(); 
     foreach (var item in items.Where(i => i != null)) 
      sb.Append(item.ToHtmlString()); 
     return MvcHtmlString.Create(sb.ToString()); 
    } 

Nó chỉ là một phương pháp hữu ích mà tôi sử dụng bên trong các lớp với các phương thức mở rộng cho HtmlHelper.

0

Tôi biết đây là siêu cũ, nhưng chưa một cách khác (mà tôi tìm được thêm thanh lịch), là sử dụng một tình trạng quá tải của các chuỗi thức Concat, mà định nghĩa siêu dữ liệu là

public static String Concat(params object[] args); 

rằng về cơ bản ToStrings mỗi một đối tượng được truyền vào và sau đó ghép các kết quả và trả về chuỗi được ghép nối.

Vì vậy, kết quả cuối cùng sẽ là:

var result = MvcHtmlString.Create(
    string.Concat(
     label, textbox, validation 
    ) 
);