MvcHtmlStringとは何ですか、いつ使用する必要がありますか?


221

ドキュメントMvcHtmlStringはひどく啓発されていません:

再度エンコードしないでくださいHTMLエンコードされた文字列を表します。

これが何を意味するのかははっきりしません。一部のHTMLヘルパーメソッドはを返すようMvcHtmlStringですが、カスタムヘルパーのオンラインで見たいくつかの例は、通常の文字列を返します。

質問:

とはMvcHtmlString

私はときを選択する必要がありますMvcHtmlStringオーバーstringとその逆?どうして?

回答:


246

ASP.NET 4では、新しいコードナゲット構文が導入されています<%: %>。本質的に、に<%: foo %>変換され<%= HttpUtility.HtmlEncode(foo) %>ます。チームは、開発者がXSSを防ぐため<%: %>に、<%= %>可能な限り代わりに使用するように努めています。

ただし、これにより、コードナゲットがその結果をすでにエンコードしている場合、<%: %>構文によって再エンコードされるという問題が発生します。これは、IHtmlStringインターフェイス(.NET 4の新機能)の導入によって解決されました。foo()<%: foo() %>IHtmlString を返す場合、<%: %>構文はそれを再エンコードしません。

MVC 2のヘルパーはMvcHtmlStringを返します。MvcHtmlStringはASP.NET 4でインターフェイスIHtmlStringを実装します。したがって、開発者<%: Html.*() %>がASP.NET 4で使用する場合、結果は二重にエンコードされません。

編集:

この新しい構文の直接的な利点は、ビューが少しクリーンになることです。たとえば、の<%: ViewData["anything"] %>代わりに書くことができます<%= Html.Encode(ViewData["anything"]) %>


MVC 2は4ではなく.Net 3.5に対してコンパイルされることを追加します。これは、4にのみ存在するため、MvcHtmlString実装されないことを意味しますIHtmlString<%:構文はダックタイプでなければなりません。インターフェイス.ToHtmlString().ToString()関係なく、常に前に呼び出されます。
キース

2
私は修正スタンド-実際MvcHtmlString.Createの方法の検出されたか否かをIHtmlString利用可能であり、動的にそれがある場合はそれをサポートするために返されたクラスを作成します。windowsitpro.com/article/net-framework/Encoding-and-Strings/...
キース・

フォローアップ: MvcHtmlStringとHtmlStringの間に意味のある違いはありますか?上記のリンクされたドキュメントを読んだ後、私はまだMvcHtmlStringがHtmlStringが提供していないことを教えてくれませんでした。
フリップダウト2013年

@flipdoubt-意味のある違いはありません。
Levi

2
2つの間に非常にわずかな違いがあります。MvcHtmlStringは、null文字列を渡すと、ToString()またはToHtmlString()でString.Emptyを返します。ただし、HtmlStringは引き続きnullを返します。
rossisdead 2013年

87

これは遅い回答ですが、この質問を読んでいる人がかみそりを使用している場合、覚えておくべきことは、かみそりはデフォルトですべてをエンコードすることですMvcHtmlString、htmlヘルパーを使用することで、かみそりにエンコードする必要がないことを伝えることができます

かみそりで文字列をエンコードしないようにするには

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

Raw()を逆コンパイルすると、文字列がHtmlStringにラップされていることがわかります。

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

" HtmlStringはASP.NET 4にのみ存在します。

MvcHtmlStringは、.NET 3.5と.NET 4の両方をサポートするためにMVC 2に追加された互換性シムでした。MVC3は.NET 4のみであるため、おそらくソース互換性のためにMVC 2-> 3のHtmlStringのかなり自明なサブクラスです。" ソース


11

これは、独自のHtmlHelper拡張機能を作成する場合に便利です。たとえば、<link>タグの構文を覚えようとするのは嫌なので、タグを作成するための独自の拡張メソッドを作成しました<link>

<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

Stringこのメソッドから戻ることもできましたが、次の場合は壊れます。

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

ではMvcHtmlString、どちらか一方<%: ... %>または<%= ... %>両方を使用すると正しく機能します。


7

あなたは使用することになりMvcHtmlStringますが、MVCヘルパーメソッドに生のHTMLを渡したい場合、あなたはヘルパーメソッドは、HTMLをエンコードする必要はありません。


うーん... HTMLヘルパーメソッドの要点はHTMLをエンコードすることだと思いました。それ以外の場合は、HTMLヘルパーメソッドで何をしますか?
devuxer 2010

そして、それ以外にも、ときに私はしたいと思う戻るMvcHtmlString HTMLヘルパーメソッドから?
devuxer 2010

へのパスまたはからのパス。HTMLヘルパーが事前にエスケープされたHTMLを生成し、他の人がそれを再エスケープしないようにする場合は、1を返します。
SLaks

1
わかりました。少し近づいていると思いますが、(賢いお尻として遭遇するリスクがあるので)他の人にそれを再エスケープしてほしいかどうかはどうやって決めるのですか?エスケープされたhtmlをいじる能力を誰かに与えることは、一般的に良い/悪い習慣ですか?私はこのような構造を見たことがありません。「それはひものようなものですが、触れないでください...触れないようにするものがあるわけではありませんが、触れないことをお勧めします。」それは何ですか?
devuxer 2010

1
ポイントは、通常の文字列とは異なり、この文字列はすでにエンコードされているということです。したがって、触れる必要はありません。
SLaks
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.