Các thuộc tính HTML có điều kiện sử dụng Razor MVC3


100

Biến strCSSClass thường có giá trị nhưng đôi khi trống.

Tôi không muốn bao gồm một lớp trống = "" trong HTML của phần tử đầu vào này, có nghĩa là nếu strCSSClass trống, tôi không muốn thuộc tính class = nào cả.

Sau đây là một cách để thực hiện một thuộc tính HTML có điều kiện:

<input type="text" id="@strElementID" @(CSSClass.IsEmpty() ? "" : "class=" + strCSSClass) />

Có cách nào thanh lịch hơn để làm điều này không? Cụ thể là một trong những nơi tôi có thể làm theo cùng một cú pháp được sử dụng trong các phần khác của phần tử: class = "@ strCSSClass"?

Câu trả lời:


160

Bạn đã không nghe thấy điều đó từ tôi, PM cho Razor, nhưng trong Razor 2 (Trang web 2 và MVC 4), chúng tôi sẽ có các thuộc tính có điều kiện được tích hợp vào Razor (kể từ khi MVC 4 RC được thử nghiệm thành công), vì vậy bạn có thể nói những thứ như thế này...

<input type="text" id="@strElementID" class="@strCSSClass" />

Nếu strCSSClass là null thì thuộc tính lớp sẽ không hiển thị chút nào.

SSSHHH ... không nói. :)


1
Yup, bạn chắc chắn không nên chấp nhận câu trả lời của tôi. Điều đó nói lên rằng, ngày nay không có cách nào sạch hơn để làm điều đó (do đó chúng tôi đang tạo ra một cách sạch hơn để làm điều đó). Có lẽ cách tốt nhất để làm điều đó là sử dụng Html.TextBox, nhưng điều đó có một số thứ khác ít mong muốn hơn đối với nó. :( Rất vui vì bạn thích những gì chúng tôi đang thêm vào. :)
Erik Porter

1
Nhưng làm thế nào tôi có thể kết hợp các thuộc tính Razor với văn bản khác? Tôi cần thực hiện như sau: ... id = "track_@track.ID". Tôi đã mong đợi một cái gì đó giống như ... id = "track_2", nhưng nó đã tạo ra kết quả sau: ... id = "track_@track.ID" ...
Laserson

2
Bạn có thể buộc Razor đánh giá mã bằng cách đặt các parens xung quanh nó. id = "track _ @ (track.ID)"
Erik Porter

1
Đã thêm ghi chú cho biết điều này hoạt động thành công với MVC 4. Nếu bạn đang ở trên MVC 3, hãy xem câu trả lời của tôi bên dưới.
AaronLS

4
@ErikPorter VUI LÒNG KHÔNG NHẮN TIN VỚI HTML CỦA TÔI !! cũng xem stackoverflow.com/questions/9234467/… điều này cũng như các hành vi xấu khác
eaglestorm

126

Lưu ý rằng bạn có thể làm điều gì đó như sau (ít nhất là trong MVC3):

<td align="left" @(isOddRow ? "class=TopBorder" : "style=border:0px") >

Những gì tôi tin là dao cạo thêm dấu ngoặc kép thực sự là trình duyệt. Như Rism đã chỉ ra khi thử nghiệm với MVC 4 (tôi chưa thử nghiệm với MVC 3 nhưng tôi cho rằng hành vi không thay đổi), điều này thực sự tạo ra class=TopBordernhưng các trình duyệt có thể phân tích cú pháp này tốt. Các trình phân tích cú pháp HTML hơi tha thứ cho việc thiếu dấu ngoặc kép thuộc tính, nhưng điều này có thể bị hỏng nếu bạn có khoảng trắng hoặc ký tự nhất định .

<td align="left" class="TopBorder" >

HOẶC LÀ

<td align="left" style="border:0px" >

Có gì sai khi cung cấp báo giá của riêng bạn

Nếu bạn cố gắng sử dụng một số quy ước C # thông thường cho các dấu ngoặc kép lồng nhau, bạn sẽ nhận được nhiều báo giá hơn mức bạn đã mặc cả vì Razor đang cố gắng thoát khỏi chúng một cách an toàn. Ví dụ:

<button type="button" @(true ? "style=\"border:0px\"" : string.Empty)>

Điều này sẽ đánh giá đến <button type="button" style="border:0px">nhưng Razor thoát khỏi tất cả đầu ra từ C # và do đó tạo ra:

style=&quot;border:0px&quot;

Bạn sẽ chỉ thấy điều này nếu bạn xem phản hồi qua mạng. Nếu bạn sử dụng trình kiểm tra HTML, thường thì bạn đang thực sự thấy DOM, không phải HTML thô. Các trình duyệt phân tích cú pháp HTML thành DOM và biểu diễn DOM sau khi phân tích cú pháp đã có một số tính năng tốt được áp dụng. Trong trường hợp này, Trình duyệt thấy không có dấu ngoặc kép xung quanh giá trị thuộc tính, hãy thêm chúng vào:

style="&quot;border:0px&quot;"

Nhưng trong trình kiểm tra DOM, mã ký tự HTML hiển thị đúng cách để bạn thực sự thấy:

style=""border:0px""

Trong Chrome, nếu bạn nhấp chuột phải và chọn Chỉnh sửa HTML, nó sẽ chuyển ngược trở lại để bạn có thể thấy những mã ký tự HTML khó chịu đó, giúp bạn rõ ràng là có dấu ngoặc kép thực bên ngoài và dấu ngoặc kép bên trong được mã hóa HTML.

Vì vậy, vấn đề với việc cố gắng tự mình thực hiện trích dẫn là Razor thoát khỏi những điều này.

Nếu bạn muốn kiểm soát hoàn toàn các báo giá

Sử dụng Html.Raw để ngăn việc thoát trích dẫn:

<td @Html.Raw( someBoolean ? "rel='tooltip' data-container='.drillDown a'" : "" )>

Kết xuất dưới dạng:

<td rel='tooltip' title='Drilldown' data-container='.drillDown a'>

Ở trên là hoàn toàn an toàn vì tôi không xuất bất kỳ HTML nào từ một biến. Biến duy nhất có liên quan là điều kiện bậc ba. Tuy nhiên, hãy cẩn thận rằng kỹ thuật cuối cùng này có thể khiến bạn gặp một số vấn đề bảo mật nhất định nếu xây dựng chuỗi từ dữ liệu do người dùng cung cấp. Ví dụ: nếu bạn đã tạo một thuộc tính từ các trường dữ liệu có nguồn gốc từ dữ liệu do người dùng cung cấp, hãy sử dụng Html.Raw có nghĩa là chuỗi đó có thể chứa phần cuối cùng của thuộc tính và thẻ, sau đó bắt đầu thẻ tập lệnh thực hiện điều gì đó thay mặt cho người đang đăng nhập người dùng (có thể khác với người dùng đã đăng nhập). Có thể bạn có một trang với danh sách tất cả ảnh của người dùng và bạn đang đặt chú giải công cụ làm tên người dùng của mỗi người và một người dùng tự đặt tên cho mình'/><script>$.post('changepassword.php?password=123')</script> và bây giờ bất kỳ người dùng nào khác xem trang này đều có mật khẩu của họ ngay lập tức được thay đổi thành mật khẩu mà người dùng độc hại biết.


Đó là một điểm rất tốt! Và trên thực tế, nó làm cho nó có thể đọc được và sử dụng được trong hầu hết các tình huống.
Dmytro Shevchenko

Đó là những gì tôi đã làm trong ví dụ trong câu hỏi của tôi. Cảm ơn vì một lời giải thích và ví dụ phức tạp hơn. :)
tony722

1
Hãy cẩn thận với khoảng trống. "style = display: none;" ám như none; = "": = "" style = "display"
wmcainsh

1
Vậy tại sao không làm việc này lại: dấu ngoặc kép ma thuật <span @ (true "class = logo-chủ sở hữu": string.Empty) /> Nó chỉ sản xuất <span class = logo-chủ sở hữu />
rism

1
@AaronLS Vâng, đó chính xác là cách của họ. Tôi không hiểu trình duyệt (Chrome 40 / FF33.1 / IE 10) sẽ ảnh hưởng như thế nào đến bất cứ điều gì vì đây là đánh dấu do máy chủ tạo và nếu vậy thì tại sao chỉ có hai thuộc tính lớp đó mà không cho thuộc tính lớp của nút hỏi hoặc thậm chí là loại = thuộc tính "nút" của cả ba nút. Chắc chắn là một thứ máy chủ IMHO vì tôi cũng có thể RDP vào một vài máy ảo Azure rải rác trên toàn cầu cho kết quả tương tự IE / Firefox / Chrome.
rism

12

Tôi đoán một cách thuận tiện và có cấu trúc hơn một chút là sử dụng trình trợ giúp Html. Theo quan điểm của bạn, nó có thể giống như sau:

@{
 var htmlAttr = new Dictionary<string, object>();
 htmlAttr.Add("id", strElementId);
 if (!CSSClass.IsEmpty())
 {
   htmlAttr.Add("class", strCSSClass);
 }
}

@* ... *@

@Html.TextBox("somename", "", htmlAttr)

Nếu cách này hữu ích cho bạn, tôi khuyên bạn nên xác định từ điển htmlAttrtrong mô hình của mình để chế độ xem của bạn không cần bất kỳ @{ }khối logic nào (hãy rõ ràng hơn).


4
-1, không bao giờ khuyến nghị ai đó đưa logic vào các quan điểm. Các khung nhìn chỉ nên chịu trách nhiệm hiển thị. Thay vào đó, hãy thêm một ví dụ HtmlHelper và tôi sẽ cung cấp cho bạn +1.
jgauffin

1
Để kiểm tra những thứ, tôi có thể sử dụng khối mã trong chế độ xem - nó nhanh hơn. Và khuyến nghị của tôi là chuyển khối này thành mô hình.
Yaschur

3
có, nhưng câu trả lời nên hiển thị phương pháp tốt nhất chứ không phải phiên bản nhanh và bẩn khiến việc bảo trì mã trở thành cơn ác mộng.
jgauffin

@jgauffin Tôi nghĩ trình trợ giúp Html ở đây là không cần thiết. xem câu trả lời của tôi.
gdoron đang hỗ trợ Monica

+1 @Yaschur Câu trả lời của bạn thật truyền cảm. Hãy tiếp tục phát huy. I E. với tính năng chuyển đổi rõ ràng của C #, chúng tôi có thể nâng cao câu trả lời này hơn nữa. Không phải tất cả các mã phải được định hình theo một cách nhất định. Luôn luôn có một cách tốt hơn mà chúng tôi không nhận thức được. Và một số dự án có lợi cho tổ chức mã. Tổ chức mã theo thực tế không phải là khái niệm!
Bamboo
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.