文本区域中的新行字符会增加 C# 中的文本长度

New line characters in text area increases text length in C#

本文关键字:文本 增加 字符 区域 新行      更新时间:2023-09-26

我在 asp.net mvc应用程序中遇到了这个问题。

在我的一个模型中,有一个字段"描述"。此字段的数据库列设置为 NVarchar(300)

在我看来,我正在创建一个文本区域,如下所示。

@Html.TextAreaFor(m => m.Description, new { maxlength = "300" })

我正在使用"jquery.validate.unobtrusive.min.js"进行客户端验证。因此,当用户在文本区域中键入内容且内容长度超过 300 个字符时,它会显示消息"请输入不超过 300 个字符"。

一切正常,直到下一个sceanario到来。用户在文本区域中输入以下数据。

f
f
f
f
f
f
f
f
sdfa

(此内容有8行新行)

根据"不显眼"验证,此内容的长度为 300(将每个新行"'"计为单个字符),因此验证通过并回发页面。

在我的 C# 代码中,由于编码,相同的内容变为 fo 长度为 308(将每个新行"''r'"计为 2 个字符),这在 tern 中使数据库操作失败,因为它只允许 300 个字符。

如果有人说我应该在这个特定属性上StringLength属性,我有以下原因没有它。

如果我放置此属性,则不会对此特定属性进行客户端验证,它会转到服务器,并且由于模型无效,它会返回页面并显示错误消息。

请告诉我可能的解决方案是什么?

在通过 @Chris 仔细查看解决方案后,我发现这将导致除具有 @maxlength 属性的 textarea 以外的任何控件出现无限循环。
此外,我发现使用 value(=传递给验证器的文本区域的值)已经切断了前导和尾随换行符,这意味着数据库操作在尝试保存包含这些换行符的文本时仍然失败。所以这是我的解决方案:

(function ($) {
    if ($.validator) {
        //get the reference to the original function into a local variable
        var _getLength = $.validator.prototype.getLength;
        //overwrite existing getLength of validator
        $.validator.prototype.getLength = function (value, element) {
            //double count line breaks for textareas only
            if (element.nodeName.toLowerCase() === 'textarea') {
                //Counts all the newline characters ('r = return for macs, 'r'n for Windows, 'n for Linux/unix)
                var newLineCharacterRegexMatch = /'r?'n|'r/g;
                //use [element.value] rather than [value] since I found that the value passed in does cut off leading and trailing line breaks.
                if (element.value) {
                    //count newline characters
                    var regexResult = element.value.match(newLineCharacterRegexMatch);
                    var newLineCount = regexResult ? regexResult.length : 0;
                    //replace newline characters with nothing
                    var replacedValue = element.value.replace(newLineCharacterRegexMatch, "");
                    //return the length of text without newline characters + doubled newline character count
                    return replacedValue.length + (newLineCount * 2);
                } else {
                    return 0;
                }
            }
            //call the original function reference with apply
            return _getLength.apply(this, arguments);
        };
    }
})(jQuery);

我在Chrome和一些IE版本中对此进行了测试,它对我来说效果很好。

您可以在包含 jquery.validate.js 后,通过将以下内容添加到 javascript 中,将客户端验证中 getLength 的行为更改为重复计算换行符。这将导致服务器端和客户端长度方法匹配,允许您使用 StringLength 属性(我假设您对 StringLength 的问题是服务器和客户端验证方法不同)。

$.validator.prototype._getLength = $.validator.prototype.getLength;
$.validator.prototype.getLength = function (value, element) {
// Double count newlines in a textarea because they'll be turned into 'r'n by the server. 
    if (element.nodeName.toLowerCase() === 'textarea')
        return value.length + value.split(''n').length - 1;
    return this._getLength(value, element);
};