2012-06-28 8 views
8

私のasp.net mvcアプリケーションでこの問題があります。テキストエリアの改行文字がC#のテキスト長を増加させます

私のモデルの1つに「Description」というフィールドがあります。このフィールドのデータベース列は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 (単一文字として各改行「\ n」をカウント)を有する

ので、検証が通過ページの投稿が返されます。

私のC#コードでは、エンコードのために、同じ内容が長さ308 になります(新しい行 "\ r \ n"は2文字として計算されます) ternはデータベース操作に失敗します。文字。

この特定の不動産にStringLength属性が必要であると言っている人は、次の理由があります。

この属性を設定した場合、クライアント側の検証はこの特定のプロパティでは発生せず、サーバーに送信されます。モデルが有効でないため、エラーメッセージとともにページに戻ります。

これにはどのような解決策がありますか教えてください。

答えて

3

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); 
}; 
+0

スプリットは私にとってはうまく機能しませんでした。あなたのメソッドを使って数えられなかった行末改行に問題がありました。 私はこれを代わりに使用しました: '//改行文字を2つのスペースで置き換えて、サーバのカウントに一致させます。 var replacedValue = value.replace(/(\ n)/ gm、 ""); return replacedValue.length; ' 注:コードブロックは何とか2つあるはずのスペースを1つしか表示しません。 – Ben

5

@クリスによって溶液を詳しく見て取った後、私はこれは@maxlength属性を持つテキストエリア以外の制御のための無限ループの原因となることがわかりました。
さらに、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のバージョンでこれをテストし、それは私のためにうまく働きました。

関連する問題