多行文本框 - 回发时在开头添加空格

5

我在一个 .ascx 控件页面上添加了一个 Textbox,代码如下:

<asp:TextBox id="txtDescription" runat="server" Width="500" TextMode="MultiLine" Rows="2"></asp:TextBox>

当首次加载时,它会显示类似于以下内容(包括开始处的4个空格):
    Description goes here

简单来说,它是一个有两行的“多行文本框”。但是,每当我们向服务器发出“Postback”请求时,页面重新加载后,我们会得到以下结果:
        Description goes here

另一个后台请求。
            Description goes here

基本上,每次页面经过Postback刷新后,它都会在文本框的开头添加4个空格。在某些页面上,这不是问题,但是如果用户向GridView或其他控件输入大量数据,则Textbox的内容可能会向右移动20个或更多字符,有时超出Textbox的范围。
简单地说,对我们公司来说,这是一个问题,因为它在我们所有的页面上都发生了。我们的一位客户曾多次提出“...你能不能解决一下文本框开头的空格问题?”。
现在,我们采用的临时解决方法是在我们的PageLoad函数中使用以下代码,但是我们仍然在Textbox的开头留下了4个空格。而且将其部署到数百个.ascx和.aspx控件/页面并不是一个解决方案。
if (IsPostBack)
     txtDescription.Text = txtDescription.Text;

现在的大问题是,有没有人知道如何移除这些神秘的4个空格,它们不断地被添加到一个多行文本框的开头?


除了你在最后提到的黑客攻击,你通常是如何填充这个文本框的文本的? - Sam Axe
你是从哪里向这个文本框中输入值的? - Jalpesh Vadgama
您可以使用Trim函数删除空格,但我建议先找出空格的来源。就像之前添加评论的人一样,我怀疑在加载文本框时会自动添加空格。 - Craig Moore
1
@Dan-o和Jalpesh Vadgama - 我们几乎所有的文本都是通过与Postgres连接访问Datareader,从我们的数据库中加载字符串。有一些情况下,我们的应用程序没有使用默认值初始化多行文本框,但是同样的问题也会发生-在开头添加了4个空格。正常的文本框(单行)不受影响。 - Alex Bunn
1
@CraigMoore - 这就是问题所在 - 我们无法找出这些空格来自哪里。使用Trim()似乎只能删除前4个空格。 - Alex Bunn
请发布插入以下代码的代码:Description goes here。这显然不是标准的文本框或文本区域行为。我敢打赌你的罪魁祸首就在那里,因为有时实际空格会呈现在代码中,比如“ Description goes here”。&nbsp是空格的HTML标记,所以如果你有这些,我会将它们从文本前面删除。非明显的JS函数是寻找随机文本修改时的另一个常见罪魁祸首。 - RandomUs1r
4个回答

5
一个典型的 HTML 文本区域(多行文本框)看起来像这样:
<textarea>This is some content</textarea>

现在,如果您的输出看起来像:
<textarea>
    This is some content
</textarea>

接下来你会介绍空间问题。 当你保存这个内容时,你在开头获得了4个空格(缩进)。现在你重新加载这四个空格,突然你有了8个空格:4个来自标记和4个来自保存的内容。每次保存内容都会重复这个模式。

我不熟悉你们(ASP Web Forms)如何生成你们的内容,但这应该给你一个调查的起点。


这就是页面源代码显示的内容(除了闭合标签在第二行末尾)。可以尝试创建一个自定义的多行文本框控件并重写Render函数,看看是否存在其中的一个错误。否则,可能需要更多的时间来调查,而我们公司目前无法抽出这么多时间。 - Alex Bunn
你可以在你的SQL中轻松修复它。SELECT LTRIM(RTRIM(Column_Name)) AS Column_Name FROM Table_Name WHERE .... - Sam Axe

1
我也遇到了这个问题。可能是Mono ASP.NET的bug。
以下是我的解决办法,建立一个自定义服务器控件来替换多行文本框。
它可以与ASP.NET集成的验证框架一起使用。
有更好的想法吗?
[ValidationProperty("Text")]
[ControlValueProperty("Text")]
[DefaultProperty("Text")]
public class TextArea: WebControl, IPostBackDataHandler, IEditableTextControl
{
    protected override HtmlTextWriterTag TagKey
    {
        get { return HtmlTextWriterTag.Textarea; }
    }

    public bool CausesValidation
    {
        get
        {
            if (ViewState["CausesValidation"] == null)
                return false;
            return (bool)ViewState["CausesValidation"];
        }
        set
        {
            ViewState["CausesValidation"] = value;
        }
    }

    public string ValidationGroup
    {
        get
        {
            return (string)ViewState["ValidationGroup"] ?? "";
        }
        set
        {
            ViewState["ValidationGroup"] = value;
        }
    }

    public string Text
    {
        get
        {
            return (string)ViewState["Text"] ?? "";
        }
        set
        {
            ViewState["Text"] = value;
        }
    }

    public bool ReadOnly
    {
        get
        {
            if (ViewState["Readonly"] == null)
                return false;

            return (bool)ViewState["Readonly"];
        }
        set
        {
            ViewState["Readonly"] = value;
        }
    }

    public int Rows
    {
        get
        {
            if (ViewState["Rows"] == null)
                return 0;
            return (int)ViewState["Rows"];
        }
        set
        {
            ViewState["Rows"] = value;
        }
    }

    public int Columns
    {
        get
        {
            if (ViewState["Columns"] == null)
                return 0;
            return (int)ViewState["Columns"];
        }
        set
        {
            ViewState["Columns"] = value;
        }
    }

    protected override void AddAttributesToRender(HtmlTextWriter writer)
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);

        if (Enabled && !IsEnabled)
            writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
        if (ReadOnly)
            writer.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "readonly");

        if (Rows != 0)
            writer.AddAttribute(HtmlTextWriterAttribute.Rows, Rows.ToString(NumberFormatInfo.InvariantInfo));
        if (Columns != 0)
            writer.AddAttribute(HtmlTextWriterAttribute.Cols, Columns.ToString(NumberFormatInfo.InvariantInfo));

        base.AddAttributesToRender(writer);
    }

    public override void RenderControl(HtmlTextWriter writer)
    {
        RenderBeginTag(writer);
        writer.WriteEncodedText(Text);
        RenderEndTag(writer);
    }

    public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        var strPostBack = postCollection[postDataKey];
        if (ReadOnly || Text.Equals(strPostBack, StringComparison.Ordinal))
            return false;
        Text = strPostBack;
        return true;
    }

    public void RaisePostDataChangedEvent()
    {
        if (!Page.IsPostBackEventControlRegistered)
        {
            Page.AutoPostBackControl = this;
            if (CausesValidation)
                Page.Validate(ValidationGroup);
        }
        TextChanged(this, EventArgs.Empty);
    }

    public event EventHandler TextChanged = delegate { };
}

抱歉回复晚了,刚刚有时间测试了一下。初步测试结果很有希望。我会再进行更多的测试,如果一切看起来都不错,我会将其标记为已接受。 - Alex Bunn

0
我也遇到过同样的问题。为了删除额外的空格,请使用textbox_TextChanged事件并将其绑定到文本框。
protected void txtDescription_TextChanged(object sender, EventArgs e)
{
String strReplace = Regex.Replace(txtDescription.Text.Trim(),@"\t|\n|\r","");
txtDescription.Text = strReplace;
}

将TextChanged事件绑定到文本框:

<asp:TextBox id="txtDescription" runat="server" Width="500" TextMode="MultiLine" Rows="2" OnTextChanged="txtDescription_TextChanged"></asp:TextBox>

注意:它不会删除第一个空格,但会处理后续的空格。


-1

你唯一的选择是在代码中设置断点,查看它们从哪里出现。


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