Apa itu MvcHtmlString dan kapan saya harus menggunakannya?


221

The dokumentasi untuk MvcHtmlStringtidak terlalu mencerahkan:

Merupakan string yang dikodekan HTML yang seharusnya tidak dikodekan lagi.

Tidak jelas bagi saya apa implikasi sebenarnya dari ini. Tampaknya beberapa metode HTML helper mengembalikan sebuah MvcHtmlString, tetapi beberapa contoh yang saya lihat online dari custom helpers hanya mengembalikan string biasa.

Pertanyaan:

Apa itu MvcHtmlString?

Ketika saya harus memilih MvcHtmlStringlebih stringdan sebaliknya? Mengapa?

Jawaban:


246

ASP.NET 4 memperkenalkan sintaks nugget kode baru <%: %>. Pada dasarnya, <%: foo %>diterjemahkan menjadi <%= HttpUtility.HtmlEncode(foo) %>. Tim berusaha membuat pengembang menggunakan <%: %>alih-alih <%= %>sedapat mungkin untuk mencegah XSS.

Namun, ini menimbulkan masalah bahwa jika kode nugget sudah meng-encode hasilnya, <%: %>sintaks akan mengkodekan ulang itu. Ini diselesaikan dengan pengenalan antarmuka IHtmlString (baru dalam. NET 4). Jika foo () dalam <%: foo() %>mengembalikan IHtmlString, <%: %>sintaks tidak akan menyandikan ulang.

Pembantu MVC 2 mengembalikan MvcHtmlString, yang pada ASP.NET 4 mengimplementasikan antarmuka IHtmlString. Karenanya ketika pengembang menggunakan <%: Html.*() %>ASP.NET 4, hasilnya tidak akan dikodekan ganda.

Edit:

Manfaat langsung dari sintaks baru ini adalah bahwa pandangan Anda sedikit lebih bersih. Misalnya, Anda dapat menulis <%: ViewData["anything"] %>alih-alih <%= Html.Encode(ViewData["anything"]) %>.


Saya akan menambahkan bahwa MVC 2 dikompilasi melawan. Net 3.5, bukan 4. Ini berarti bahwa MvcHtmlStringtidak mengimplementasikan IHtmlStringkarena hanya ada di 4. <%:Sintaks harus tipe bebek - itu akan selalu memanggil .ToHtmlString()sebelumnya .ToString()terlepas dari antarmuka.
Keith

2
Saya berdiri dikoreksi - sebenarnya MvcHtmlString.Createmetode ini mendeteksi apakah IHtmlStringtersedia dan secara dinamis membuat kelas yang dikembalikan untuk mendukungnya jika: windowsitpro.com/article/net-framework/Encoding-and-Strings/…
Keith

Tindak Lanjut: Apakah ada perbedaan yang berarti antara MvcHtmlString dan HtmlString? Setelah membaca dokumen yang ditautkan di atas, saya masih tidak tahu apa yang MvcHtmlString berikan kepada saya bahwa HtmlString tidak.
flipdoubt

@ flipdoubt - Tidak ada perbedaan yang berarti.
Levi

2
Ada satu perbedaan yang sangat kecil antara keduanya. MvcHtmlString akan mengembalikan String.Empty di ToString () atau ToHtmlString () jika Anda memberikannya string nol. HtmlString akan terus mengembalikan nol.
rossisdead

87

Ini adalah jawaban yang terlambat tetapi jika ada orang yang membaca pertanyaan ini menggunakan pisau cukur, yang harus Anda ingat adalah bahwa pisau cukur mengkodekan semuanya secara default, tetapi dengan menggunakan MvcHtmlStringbantuan html Anda, Anda dapat memberi tahu pisau cukur bahwa itu tidak perlu dikodekan .

Jika Anda ingin pisau cukur tidak mengkodekan penggunaan string

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

Decompiling Raw (), menunjukkan kepada kita bahwa itu membungkus string dalam HtmlString

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

" HtmlString hanya ada di ASP.NET 4.

MvcHtmlString adalah shim kompatibilitas ditambahkan ke MVC 2 untuk mendukung keduanya. NET 3.5 dan .NET 4. Sekarang MVC 3 adalah .NET 4 saja, itu adalah subkelas HtmlString yang cukup sepele mungkin untuk MVC 2-> 3 untuk kompatibilitas sumber. " sumber


11

Penggunaan praktis yang baik dari ini adalah jika Anda ingin membuat HtmlHelperekstensi sendiri . Misalnya, saya benci mencoba mengingat <link>sintaks tag, jadi saya telah membuat metode ekstensi saya sendiri untuk membuat <link>tag:

<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

Saya bisa saja kembali Stringdari metode ini, tetapi jika saya memiliki yang berikut ini akan rusak:

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

Dengan MvcHtmlString, menggunakan salah satu <%: ... %>atau <%= ... %>keduanya akan bekerja dengan benar.


7

Anda akan menggunakan MvcHtmlStringjika Anda ingin meneruskan HTML mentah ke metode bantuan MVC dan Anda tidak ingin metode bantuan untuk menyandikan HTML.


Hmm ... Saya pikir inti dari metode HTML helper adalah menyandikan HTML. Apa yang akan saya lakukan dengan metode pembantu HTML?
devuxer

Dan, selain itu, ketika akan saya ingin kembali suatu MvcHtmlStringdari metode pembantu HTML?
devuxer

Lewati atau kembali dari. Anda ingin mengembalikannya jika helper HTML Anda menghasilkan HTML yang telah lolos sebelumnya dan Anda tidak ingin orang lain menghindarinya kembali.
SLaks

1
Oke, saya pikir itu membuat saya sedikit lebih dekat, tetapi (dengan risiko dianggap sebagai orang yang pintar), bagaimana saya memutuskan apakah saya ingin orang lain melarikan diri lagi? Apakah itu praktik yang baik / buruk secara umum untuk memberi seseorang kemampuan untuk mengacaukan html yang lolos? Saya belum pernah melihat konstruk seperti ini sebelumnya. "Ini seperti tali, tapi tolong jangan menyentuhnya ... tidak ada yang mencegahmu menyentuhnya, tapi kami lebih suka kamu tidak menyentuhnya." Tentang apa itu?
devuxer

1
Intinya adalah bahwa tidak seperti string biasa, ini string yang telah dikodekan. Karena itu, tidak perlu menyentuhnya.
SLaks
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.