简体   繁体   English

文本区域中的换行符增加了C#中的文本长度

[英]New line characters in text area increases text length in C#

I have this problem in my asp.net mvc application. 我在asp.net mvc应用程序中遇到此问题。

In one of my model there is a field "Description". 在我的一个模型中有一个字段“描述”。 The database column for this fields is set to NVarchar(300) . 此字段的数据库列设置为NVarchar(300)

In my view I am creating aa text area as following. 在我看来,我正在创建一个文本区域如下。

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

I am using "jquery.validate.unobtrusive.min.js" for client side validation. 我正在使用“jquery.validate.unobtrusive.min.js”进行客户端验证。 So when user types in the textarea and content length goes more than 300 characters it displays message "Please enter no more than 300 characaters." 因此,当textarea中的用户类型和内容长度超过300个字符时,它会显示消息“请输入不超过300个字符”。

Everything works fine till the following sceanario comes. 一切正常,直到下面的情景来临。 User enters following data in the text area. 用户在文本区域中输入以下数据。

f
f
f
f
f
f
f
f
sdfa

(this content has 8 new lines) (此内容有8条新线)

According to "unobtrusive" validation this content has length 300 (counting each new line "\\n" as a single character) so the validation passes and page posts back. 根据“不显眼”验证,此内容的长度为300 (将每个新行“\\ n”计为单个字符),以便验证通过并返回页面帖子。

In my C# code, due to Encoding, the same content becomes fo length 308 (Counting each new line "\\r\\n" as 2 characters) which in tern fails the data base operation as it only allows 300 characters. 在我的C#代码中,由于编码,相同的内容变为长度308 (将每个新行“\\ r \\ n”计为2个字符) ,这使得数据库操作失败,因为它只允许300个字符。

If someone is saying that I should have StringLength attribute on this particular property, I have the following reason for not having it. 如果有人说我应该在这个特定的属性上有StringLength属性,我有以下原因没有它。

If I put this attribute the client-side validation does not happen for this particular property, it goes to the server and since the model is not valid it comes back to the page with error message. 如果我将此属性设置为此特定属性不会发生客户端验证,则会转到服务器,因为模型无效,所以它会返回到包含错误消息的页面。

Please advise me what could be the possible solution for this? 请告诉我可能的解决方案是什么?

After taking a closer look at the solution by @Chris, I found that this would cause an endless loop for any control other than textarea with the @maxlength attribute. 在仔细研究了@Chris的解决方案之后,我发现除了带有@maxlength属性的textarea之外,这将导致无限循环。
Furthermore, I found that using value (=the value of the textarea passed into the validator) would already have the leading and trailing line breaks cut off, which means the database operation still failed when it tried to save text containing those line breaks. 此外,我发现使用value (=传递给验证器的textarea的值)已经将前导和尾部换行符切断,这意味着当它尝试保存包含这些换行符的文本时数据库操作仍然失败。
So here is my solution: 所以这是我的解决方案:

(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);

I tested this in Chrome and a few IE versions and it worked fine for me. 我在Chrome和一些IE版本中对此进行了测试,它对我来说很好。

You can change the behavior for getLength in client validation to double count newlines by adding the following to your javascript after you've included jquery.validate.js. 您可以通过在包含jquery.validate.js之后将以下内容添加到javascript中来更改客户端验证中getLength的行为以将新行重复计算。 This will cause the server-side and client-side length methods to match letting you use the StringLength attribute (I assume your issue with StringLength was that the server and client validation methods differed). 这将导致服务器端和客户端长度方法匹配,让您使用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);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM