Visual Web Developer 用新的 HTML 替换内部 HTML

Posted

技术标签:

【中文标题】Visual Web Developer 用新的 HTML 替换内部 HTML【英文标题】:Visual Web Developer Replace Inner HTML With New HTML 【发布时间】:2012-06-10 22:49:31 【问题描述】:

我已经制作了一个网页来显示一个图形,然后允许用户在它下面输入一些 cmets。提示用户输入,我试图将每个评论存储在一个列表中,然后将该列表显示为一个有序的 html 列表。以下是相关代码:

<script runat="server">

private List<string> messages = new List<string>();

protected void Button2_Click(object sender, EventArgs e)

    messages.Add(TextBox2.Text);
    TextBox2.Text = "";


protected void Button3_Click(object sender, EventArgs e)

    messages.Clear();


protected void Button4_Click(object sender, EventArgs e)

    string output = "<ol>";
    foreach (string message in messages)
    
        output += "<li>";
        output += message;
        output += "</li>";
    
    output += "</ol>";
    Message.InnerHtml = Server.HtmlEncode(output);


protected void Chart1_Load(object sender, EventArgs e)




</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        Key Messages:<br />
        <span id="Message" runat="server">
            <asp:TextBox runat="server" ID="TextBox2" Width="500px"></asp:TextBox>
            <asp:Button runat="server" ID="Button2" Text="Enter Message" Onclick="Button2_Click" />
            <asp:Button runat="server" ID="Button3" Text="Clear Messages" onclick="Button3_Click" />
            <asp:Button runat="server" ID="Button4" Text="Done" onclick="Button4_Click" />
        </span>
    </div>
    </form>
</body>
</html>

由此产生的输出是:

Key Messages:
<ol></ol>

所以我有两个谜团:

1) 为什么输入到文本框中的文本没有被添加到列表中

2) 为什么新的 HTML 显示为纯文本。

感谢任何建议。

问候。

【问题讨论】:

【参考方案1】:

1) 为什么输入到文本框中的文本没有添加到列表中

正如其他人所说,您没有在请求之间保留数据。 当您单击一个按钮时,整个页面都会重新实例化,从而导致您的 message 变量自行重新设置。

Session 可以使用。例如,将您的 message 字段替换为如下属性:

private List<string> Messages

    get
    
        var messages = Session["Messages"] as List<string>;

        if (messages == null)
        
            messages = new List<string>();
            Session["Messages"] = messages;
        

        return messages;
    

2) 为什么新的 HTML 显示为纯文本。

(附注&lt;span&gt; 内的&lt;ol&gt; 标签是无效的Html,即使它可以呈现)

您正在编码您的output。 要获得所需的结果,您只需不要像这样对其进行编码:

(我对此不是 100% 确定,但我认为在实时系统上通过 IIS 运行时,IIS 可能会自动编码字符串并且您再次遇到同样的问题,请查看建议的 BulletList 作为替代如果是这样的话。)

protected void Button4_Click(object sender, EventArgs e)

    string output = "<ol>";
    foreach (string message in Messages)
    
        output += "<li>";
        output += message;
        output += "</li>";
    
    output += "</ol>";
    Message.InnerHtml = output;

另一种方法是使用BulletList 使用BulletStyleNumbered 来获得相同的结果。 像这样更新您的Html

<div>
    Key Messages:<br />
    <span id="Message" runat="server">
        <asp:TextBox runat="server" ID="TextBox2" Width="500px"></asp:TextBox>
        <asp:Button runat="server" ID="Button2" Text="Enter Message" OnClick="Button2_Click" />
        <asp:Button runat="server" ID="Button3" Text="Clear Messages" OnClick="Button3_Click" />
        <asp:Button runat="server" ID="Button4" Text="Done" OnClick="Button4_Click" />
    </span>

    <asp:BulletedList BulletStyle="Numbered" ID="OutputMessages" runat="server">
    </asp:BulletedList>
</div>

Button4_Click中的代码改成这样:

protected void Button4_Click(object sender, EventArgs e)

    // If you want to hide the message controls.
    Message.Visible = false;

    foreach (var message in Messages)
    
        OutputMessages.Items.Add(new ListItem(Server.HtmlEncode(message)));
    

总结

保留您的数据,例如使用Session 如果您希望传递的 html 进行渲染,请不要对数据进行编码(阅读下面的警告) 考虑使用 BulletList 而不是发回不安全的 html 字符串 &lt;span&gt; 中的 &lt;ol&gt; 标记是无效的 html

编码警告

如果不对来自服务器的数据进行编码,则可能会发送恶意脚本。例如,假设我们执行以下操作:

Message.InnerHtml = "<script>alert('Hello');</script>";

上面将执行显示警报的脚本。想象这是一个恶意脚本!

但是,如上所述,IIS 可能会自动编码字符串,在这种情况下,此脚本将不会执行,而是应呈现为纯文本。

【讨论】:

【参考方案2】:

您必须了解网页的工作原理。每次单击按钮/超链接都会创建一个新的 http 请求,并在此过程中检索一个新页面(除非您使用 ajax,但这是另一回事)。

您可以设置 List 类型的私有变量,但这仅适用于页面的当前实例。当用户发出请求(例如单击按钮)时,会创建一个新的页面实例并将其返回给用户 => 列表将始终为空。 Http 是无状态的,您需要一种方法来在请求之间执行数据的持久化。

如果列表是特定于用户的,您可以根据需要使用 ViewState 或 SessionState 来存储/检索数据。如果它是更全球化的东西,请使用数据库/文件作为持久性媒介。

【讨论】:

哎呀。位置不对。忽略这个。【参考方案3】:

列表不是静态的,因此每次请求页面时都会重新定义。

您将其视为播放文本的原因是您对输出进行了 HtmlEncode。所以 成为字符的 HTML 表示(< 和 >)。

Message.InnerHtml = output;

应该改正

【讨论】:

static 的问题在于它是应用程序范围的。即使声明 private static readonly List&lt;string&gt; Messages = new List&lt;string&gt;(); 将其更改为 static 并打开例如 FirefoxChrome (或 IE 和另一个,无论哪种方式)。您可以使用一个浏览器添加消息,然后单击另一个浏览器上的Done 并获取列表。我不认为使用 static 并在应用程序范围内共享消息是一个好方法,除非这当然是 OP 的意图。 我并不是真的指的是“静态”关键字,而是每次请求页面时对象不是静态的。对那里的混乱感到抱歉。

以上是关于Visual Web Developer 用新的 HTML 替换内部 HTML的主要内容,如果未能解决你的问题,请参考以下文章

您可以使用 Visual Web Developer 编辑 resx 文件吗?

Visual Web Developer 中的 PHP 语法高亮显示?

Visual Studio Web Developer 2010 Express 和 64 位

使用 Microsoft Visual Web Developer Express 2008 创建站点时出现问题

写入 Microsoft Visual Web Developer 调试器的 JavaScript 方法?

Visual Web Developer 2008 不会从 Linq 自动生成类