ASP.NET MVC将原始HTML从控制器传递到视图

7

我已经为此苦思冥想几天了,不确定是我的环境问题还是代码本身的问题,因为我是基于ASP.NET MVC做的(尽管我有5年C#编程经验)。我使用的是最近干净安装的Win7x64和VS 2008,并且打了所有补丁。

我在数据库表中存储了原始HTML,根据一些规则由控制器进行选择性加载,这些规则我无法控制。不幸的是,当我试图将该值放入控制器中的视图数据中时,会出现以下问题:

ViewData["HTMLData"] = DAO.HTMLDataGet();

当我看到输出结果时,它被转义/ HTML 编码了。我尝试使用以下方法解决这个问题,但都没有成功:

<%: HttpUtility.HtmlDecode(ViewData["HTMLData"].ToString())%>

并且...

<%: Server.HtmlDecode(ViewData["HTMLData"].ToString())%>

而且...

<%: Html.Raw(ViewData["HTMLData"].ToString())%>

...它可以从数据库表中获取原始的HTML,但无论我尝试什么,它都会强制编码。根据我在MSDN上阅读的内容,有一个脚注提到由于HTML未正确解码而包含空格(我的确有),可能会导致问题。既然我怀疑我不是唯一面临这个问题的人,我转向你们寻求一些想法。

我即将在视图中使用正则表达式来进行页面清理,但在我粗暴地处理之前,认为最好先从其他人那里得到一些建议。提前感谢您的帮助。


这段内容是否全部为HTML,并且需要返回到视图中? - bhuvin
我相信我已经解决了这个谜团.. 我使用的是<%: %>而不是<%= %> -- 后者解决了这个问题。对于试图让事情变得简单的微软来说,他们在ASP.Net方面做出了很多愚蠢的决定,比如这种无用的伪标记。 - Dave
@user1611050,实际上,你是对的:曾经做出了一个愚蠢的决定,那就是最初只有 <%= 可用,而 <%: 才是正确的行为(并且后来才添加),几乎所有情况下都应该使用它。在 Razor 中,他们做得很对:@foo<%:foo%> 是一样的,即编码过的。如果你认为 <%= 是更可取的行为,那么:你还没有做足够的 HTML 编程(不仅仅是 ASP.NET),也没有考虑到“xss”的问题。编写预先格式化的 HTML(从视图中)是例外,而不是常见情况。 - Marc Gravell
3个回答

17

<%: 的意思是“必要时进行编码”。如果您不想这样做,那么懒惰的方法是使用<%=,但我建议您将其包装在IHtmlString中,例如:

string yourEncodedHtml = ...
var html = new MvcHtmlString(yourEncodedHtml);

现在,如果你将that存储并显示它,它应该会按照html标签"原样"显示。


感谢您解释为什么那个解决方案有效。在我看来,他们设置它的方式真是太愚蠢了。 - Dave
2
@user1611050,为什么?几乎每次输出内容时,正确的做法都是进行编码。现在想象一下,如果你做错了,影响会有多大:双重编码比XSS攻击要好得多(也更明显)。 - Marc Gravell

8
尝试使用:<%= %>
<%= Html.Raw(ViewData["HTMLData"].ToString())%>

<%: %>是ASP.NET 4(和ASP.NET MVC)中用于HTML编码输出的语法

更多详情请点击链接

如何进行HTML编码

ASP.NET应用程序(特别是使用ASP.NET MVC的应用程序)通常依赖于<%= %>代码块表达式来呈现输出。开发人员经常在这些表达式中使用Server.HtmlEncode()或HttpUtility.Encode()辅助方法来HTML编码输出。

虽然这可以工作,但有两个缺点:

过程略显繁琐;开发人员经常会忘记调用Server.HtmlEncode方法,而且没有简单的方法来验证它在整个应用程序中的使用情况。

新的 <%: %> Code Nugget 语法

随着ASP.NET 4的发布,我们推出了一种新的代码表达式语法(<%: %>),它像<%= %>代码块一样呈现输出,但在这之前会自动对其进行HTML编码。这就消除了显式进行HTML编码的需要。

我们选择了<%: %>语法,以便可以快速替换现有的<%= %>代码块实例。它还可以让您轻松搜索代码库中的<%= %>元素,以查找和验证应用程序中未使用HTML编码的任何情况,确保您拥有正确的行为。


如果您调用 HtmlRaw,那么使用 <%:<%= 就无关紧要了,因此首选仍然是 <%:。如果第一行是 <%:Html.Raw(...)%>,那么这将是完美的答案。 - Marc Gravell

0

你尝试的方法几乎成功了。这启发了我做出了这个可行的方案:

Html.Raw(HttpUtility.HtmlDecode(ViewData["HTMLData"].ToString()))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接