什么是MvcHtmlString?何时应使用它?


221

文件MvcHtmlString不可怕启发:

表示不应再次编码的HTML编码字符串。

我不清楚这到底意味着什么。似乎有些HTML帮助器方法返回MvcHtmlString,但是我在网上看到的一些自定义帮助器示例仅返回了常规字符串。

问题:

什么是MvcHtmlString

我什么时候应该选择MvcHtmlString超过string反之亦然?为什么?

Answers:


246

ASP.NET 4引入了新的代码块语法<%: %>。本质上,<%: foo %>翻译为<%= HttpUtility.HtmlEncode(foo) %>。该团队正在尝试让开发人员使用它,<%: %>而不是<%= %>尽可能避免使用XSS。

但是,这带来了一个问题,如果代码块已经对其结果进行了编码,则<%: %>语法将对其进行重新编码。通过引入IHtmlString接口(.NET 4中的新增功能)可以解决此问题。如果FOO()<%: foo() %>返回一个IHtmlString,该<%: %>语法不会重新编码。

MVC 2的助手返回MvcHtmlString,它在ASP.NET 4上实现接口IHtmlString。因此,当开发人员<%: Html.*() %>在ASP.NET 4中使用时,结果将不会被双重编码。

编辑:

这种新语法的直接好处是您的视图更加简洁。例如,您可以编写<%: ViewData["anything"] %>而不是<%= Html.Encode(ViewData["anything"]) %>


我还要补充一点,MVC 2是针对.Net 3.5而不是4编译的。这意味着MvcHtmlString它没有实现,IHtmlString因为它仅存在于4中。<%:语法必须为duck-type-始终.ToHtmlString().ToString()接口之前调用。
基思2010年

2
我认错-其实MvcHtmlString.Create方法检测是否IHtmlString可用,并动态地创建返回的类,以支持它,如果它是:windowsitpro.com/article/net-framework/Encoding-and-Strings/...
基思

后续: MvcHtmlString和HtmlString之间有有意义的区别吗?阅读了上面链接的文档后,我仍然不知道MvcHtmlString给了我什么,而HtmlString没有给我。
flipdoubt

@flipdoubt-没有有意义的区别。
李维

2
两者之间有一个非常小的差异。如果您将其传递为空字符串,则MvcHtmlString将在ToString()或ToHtmlString()中返回String.Empty。不过,HtmlString将继续返回null。
rossisdead 2013年

87

这是一个很晚的答案,但是如果阅读此问题的任何人都在使用razor,则您应该记住的是,默认情况下,razor会对所有内容进行编码,但是通过MvcHtmlString在html helper中使用,您可以告诉razor不需要对其进行编码

如果您希望剃须刀不对字符串进行编码,请使用

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

反编译Raw(),向我们展示了它将字符串包装在HtmlString中

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

HtmlString仅存在于ASP.NET 4中。

MvcHtmlString是添加到MVC 2中以支持.NET 3.5和.NET 4的兼容性填充程序。既然MVC 3仅是.NET 4,则它是HtmlString的一个相当琐碎的子类,大概是MVC 2-> 3可以实现源兼容性。来源


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,如果你想使用原始的HTML传递到MVC的辅助方法和你不想要的helper方法来编码的HTML。


嗯...我认为HTML帮助程序方法的重点是对HTML进行编码。如果不使用HTML辅助方法,我该怎么办?
devuxer 2010年

而且,除此之外,什么时候我想从HTML帮助器方法返回一个MvcHtmlString
devuxer 2010年

传递给或返回。如果您的HTML帮助器生成了预转义的HTML,并且您不希望其他人重新转义该HTML,则需要返回一个。
SLaks's

1
好的,我认为这使我更接近一点,但是(冒着成为聪明人的风险)我该如何确定是否要让其他人重新逃脱呢?赋予某人处理转义的html的能力通常是好/坏做法吗?我以前从未见过这样的构造。“这就像一个字符串,但是请不要触摸它……不是有任何阻止您触摸它的东西,但是我们希望您不要这样做。” 那是什么意思
devuxer 2010年

1
关键是,与常规字符串不同,字符串已被编码。因此,无需触摸它。
SLaks 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.