如何允许在 asp.net 的文本框中提交 HTML 标签?

问题描述 投票:0回答:7

首先,我想让大家知道我使用的是 aspx 引擎而不是 Razor 引擎。

我有一个表格内的表格。我的一个文本框包含 html 标签,例如

</br>Phone: </br> 814-888-9999 </br> Email: </br> [email protected].  

当我去构建它时,它给了我一个错误:

从客户端检测到潜在危险的 Request.Form 值

(QuestionAnswer="...ics Phone:<br/>814-888-9999<br...")

我尝试了验证请求=“假”,但它不起作用。

很抱歉到目前为止我还没有添加我的 html 代码供您查看。如果需要的话,我正在提出一些问题,我可以在哪里编辑它。

 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"   Inherits="System.Web.Mvc.ViewPage<dynamic>" %>


<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
EditFreqQuestionsUser
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
$(document).ready(function () {
    $("#freqQuestionsUserUpdateButton").click(function () {
        $("#updateFreqQuestionsUser").submit();
    });
});
</script>
<h2>Edit Freq Questions User </h2>

<%Administrator.AdminProductionServices.FreqQuestionsUser freqQuestionsUser =   ViewBag.freqQuestionsUser != null ? ViewBag.freqQuestionsUser : new   Administrator.AdminProductionServices.FreqQuestionsUser(); %>
<%List<string> UserRoleList = Session["UserRoles"] != null ? (List<string>)Session["UserRoles"] : new List<string>(); %>
<form id="updateFreqQuestionsUser" action="<%=Url.Action("SaveFreqQuestionsUser","Prod")%>" method="post" onsubmit+>
<table> 
    <tr>
        <td colspan="3" class="tableHeader">Freq Questions User Details <input type ="hidden" value="<%=freqQuestionsUser.freqQuestionsUserId%>" name="freqQuestionsUserId"/> </td>
    </tr>
     <tr>
        <td colspan="2" class="label">Question Description:</td>
        <td class="content">
            <input type="text" maxlength="2000" name="QuestionDescription" value="  <%=freqQuestionsUser.questionDescription%>" />
        </td>
    </tr>
     <tr>
        <td colspan="2" class="label">QuestionAnswer:</td>
        <td class="content">
            <input type="text" maxlength="2000" name="QuestionAnswer" value="<%=freqQuestionsUser.questionAnswer%>" />
        </td>
    </tr>
    <tr>
        <td colspan="3" class="tableFooter">
                <br />
                <a id="freqQuestionsUserUpdateButton" href="#" class="regularButton">Save</a>
                <a href="javascript:history.back()" class="regularButton">Cancel</a>
        </td> 
    </tr>
    </table>
      </form>
</asp:Content>
c# javascript asp.net-mvc decoding
7个回答
32
投票

在提交页面之前,您需要使用 window.escape(...) 对文本框的值进行 html 编码

如果您需要服务器端未转义的文本,请使用

HttpUtility.UrlDecode(...)
方法。

非常快速的样品:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="SO.WebForm1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script>
        function makeSafe() {
            document.getElementById('TextBox1').value = window.escape(document.getElementById('TextBox1').value);
        };

        function makeDangerous() {
            document.getElementById('TextBox1').value = window.unescape(document.getElementById('TextBox1').value);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server" onsubmit="makeSafe();">
    <div>
        <asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine" Rows="10" ClientIDMode="Static"></asp:TextBox>
    </div>
    <asp:Button ID="Button1" runat="server" Text="Button" />
    </form>


     <script>
         makeDangerous();
    </script>
</body>
</html>

对您的代码进行以下更改:

<script type="text/javascript">
    $(document).ready(function () {
        makeDangerous();
        $("#freqQuestionsUserUpdateButton").click(function () {
            makeSafe();
            $("#updateFreqQuestionsUser").submit();
        });
    });

    // Adding an ID attribute to the inputs you want to validate is simplest
    // Better would be to use document.getElementsByTagName and filter the array on NAME
    // or use a JQUERY select....

    function makeSafe() {
        document.getElementById('QuestionAnswer').value = window.escape(document.getElementById('QuestionAnswer').value);
    };

    // In this case adding the HTML back to a textbox should be 'safe'
    // You should be very wary though when you use it as actual HTML
    // You MUST take steps to ensure the HTML is safe.
    function makeDangerous() {
        document.getElementById('QuestionAnswer').value = window.unescape(document.getElementById('QuestionAnswer').value);
    }
</script>

13
投票

[ValidateInput]
属性装饰你的控制器动作:

[ValidateInput(false)]
[HttpPost]
public ActionResult Foo(MyViewModel model)
{
    ...
}

3
投票

客户端 JavaScript:

function codificarTags() 
{
     document.getElementById('txtDescripcion').value = document.getElementById('txtDescripcion').value.replace(/</g,'&lt;').replace(/>/g,'&gt;');
}
    
<form id="form1" runat="server" onsubmit="codificarTags();">

服务器:

protected void Page_Load(object sender, EventArgs e)
{
     txtDescripcion.Text = txtDescripcion.Text.Replace(@"&lt;", @"<").Replace(@"&gt;", @">");
}

1
投票

我建议使用 AjaxControlToolkit 的 HTML 编辑器。我现在正在实施。如果您的文本框是多行的并且足够大以容纳 HTML,为什么不将其添加到 HTML 编辑器中呢。您的用户也会更高兴。

http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/HTMLEditor/HTMLEditor.aspx


0
投票

在文本框中使用 html 不是一个好的做法,也许使用换行符 (

Environment.NewLine
) 或 而不是
br
.NET 参考

示例(C# 语言):

textBox1.Multiline = true;
textBox1.Text = "test" + Environment.NewLine + "test2";

0
投票

我采取了一些不同的方法。我想在我的应用程序中广泛使用 html 文本框。我制作了一个用户控件,这样可以避免每次添加新控件时编辑 JavaScript。我的整个控件都是非常自定义的,但 html 处理的核心如下所示。

UserControl
标记有一些简单的JavaScript来转义和取消转义文本框。

<script type="text/javascript">

    function UnescapeControl(clientId) {
            $('#' + clientId).val(window.unescape($('#' + clientId).val()));
    }

    function EscapeAllControls() {
       var escapeControList = JSON.parse('<%= new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(EscapeControlList) %>');
       for (var i = 0; i < escapeControList.length; i++) 
           EscapeControl(escapeControList[i]);            
    }

    function EscapeControl(textClientId) {
       document.getElementById(textClientId).value = window.escape(document.getElementById(textClientId).value); 
    }
</script>

<asp:TextBox ID="Txt_SavableText" CssClass="form-control" Width="100%" runat="server" ></asp:TextBox>

后面的代码负责在回发之前使用

RegisterOnSubmitStatement
转义控件,并在回发之后使用
RegisterStartupScript
取消转义它们。

public partial class SavableTextBox : System.Web.UI.UserControl
{

    public List<string> EscapeControlList
    {
        get
        {
            if (Session["STB_EscapeControlList"] == null)
                Session["STB_EscapeControlList"] = new List<string>();
            
            return (List<string>)Session["STB_EscapeControlList"];
        }
        set { Session["STB_EscapeControlList"] = value; }
    }

    

    protected void Page_Load(object sender, EventArgs e)
    {
        if (EscapeHtmlOnPostback && !EscapeControlList.Contains(GetClientId()))
            EscapeControlList.Add(GetClientId());

        // When using a script manager, you should use ScriptManager instead of ClientScript.
        if (EscapeHtmlOnPostback)
            ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "UnescapeControl_" + GetClientId(), "UnescapeControl('" + GetClientId() + "');", true);

        // Ensure we have our escape script called before all post backs containing escapable controls.
        // This is like calling OnClientClick before everything.
        if (EscapeControlList != null && EscapeControlList.Count > 0)
            this.Page.ClientScript.RegisterOnSubmitStatement(this.GetType(), "SaveableTextBoxEscaper", "EscapeAllControls();");
        
    }


   public string Text
    {
        get
        {
            return Txt_SavableText.Text;
        }
        set
        {
            Txt_SavableText.Text = value;
        }
    }

    public string GetClientId()
    {
        return Txt_SavableText.ClientID;
    }
}

现在我们可以在设置时像这样在任何地方使用它

EscapeHtmlOnPostback="True"

<%@ Register TagPrefix="STB" TagName="SavableTextBox" Src="~/SavableTextBox.ascx" %>
<STB:SavableTextBox ID="Txt_HtmlTextBox" EscapeHtmlOnPostback="True" runat="server" />

注意,当我们在回发期间访问

Txt_HtmlTextBox.Text
时,它已经为我们转义了。


0
投票

我喜欢@clamchoda 的用户控制解决方案,并试用了它。正如他提到的,他的整个控件都是非常自定义的,并且代码反映了更复杂的需求。对于更简单的事情,您可能需要考虑以下内容。

请注意,在此版本中,文本会在回发时自动解码,因此您的页面代码不必这样做(就像使用标准 TextBox 控件一样)。

用户控件 HTML 标记:

<script>
   document.forms[0].addEventListener("submit", function (e){
      let txtBox = document.getElementById('<%= TxtBox.ClientID %>')
      txtBox.value = window.escape(txtBox.value);
   });
</script>

<asp:TextBox ID="TxtBox" runat="server" />

代码隐藏(在 VB 中,但很容易转换为 C#):

Public Property Text As String
   Get
      Return TxtBox.Text
   End Get
   Set
      TxtBox.Text = Value
   End Set
End Property

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

   If IsPostBack Then
      TxtBox.Text = Uri.UnescapeDataString(TxtBox.Text)
   End If

End Sub

以上是基本内容。为了允许在 HTML 中进行标记,我添加了如下属性(从最有用的属性开始,并根据出现的给定需求逐渐添加其他属性):

Public Property CssClass As String
   Get
      Return TxtBox.CssClass
   End Get
   Set
      TxtBox.CssClass= Value
   End Set
End Property

Public Property StyleMargin() As String
   'Note: use this to set all four margins.
   Get
      Return TxtBox.Style("margin")
   End Get
   Set(ByVal value As String)
      TxtBox.Style.Add("margin", value)
   End Set
End Property

Public Property Width As String
   Get
      Return TxtBox.Width
   End Get
   Set
      TxtBox.Width= Unit.Parse(value)
   End Set
End Property

最后,与所有最佳实践相比,要访问代码隐藏中的完整 TextBox 属性,您可以使用:

Public ReadOnly Property TxtBoxControl() As TextBox
   '==>   USE RESPONSIBLY !!!   <===
   Get
      Return TxtBox
   End Get
End Property

如前所述,要在页面上使用它,您需要在 HTML 标记中注册用户控件:

<%@ Register TagPrefix="STB" TagName="PostBackSafeTextBox" Src="~/PostBackSafeTextBox.ascx" %>

<STB:PostBackSafeTextBox ID="MyTextBoxTxt" runat="server" />

希望以上内容对其他人有帮助。也就是说,这必须归功于@clamchoda,他首先提出了这个想法。谢谢@clamchoda——它真的救了我!

© www.soinside.com 2019 - 2024. All rights reserved.