2012-06-28 13 views
8

Mam ten problem w mojej aplikacji mvc asp.net.Nowe znaki linii w obszarze tekstowym zwiększają długość tekstu w C#

W jednym z moich modeli znajduje się pole "Opis". Kolumna bazy danych dla tych pól jest ustawiona na NVarchar(300).

Moim zdaniem, tworzę obszar tekstowy w następujący sposób.

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

Używam "jquery.validate.unobtrusive.min.js" do sprawdzania poprawności strony klienta. Więc kiedy użytkownik wpisze w polu tekstowym i długość treści przekroczy 300 znaków, wyświetli komunikat "Proszę podać nie więcej niż 300 znaków".

Wszystko działa poprawnie, dopóki nie pojawi się następujący sceanario. Użytkownik wprowadza następujące dane w polu tekstowym.

f 
f 
f 
f 
f 
f 
f 
f 
sdfa 

(Ta zawartość 8 nowe linie)

Według „dyskretnego” walidacji Zawartość ta ma długość 300 (liczenie każdej nowej linii „\ n”, jako pojedynczego znaku) więc przechodzi walidację i posty z powrotem.

W moim kodu C#, ze względu na Kodowanie, sama treść staje fo długości 308 (licząc każdą nową linię „\ r \ n” jak 2 znaków) które w tern nie przejdzie operację bazy danych, gdyż pozwala jedynie 300 postacie.

Jeśli ktoś mówi, że powinienem mieć atrybut StringLength na tej konkretnej właściwości, mam następujący powód, dla którego go nie posiadam.

Jeśli wstawię ten atrybut, walidacja po stronie klienta nie nastąpi dla tej konkretnej właściwości, przechodzi do serwera, a ponieważ model jest nieprawidłowy, wraca do strony z komunikatem o błędzie.

Proszę mi doradzić, jakie może być możliwe rozwiązanie tego problemu?

Odpowiedz

3

Możesz zmienić zachowanie getLength w walidacji klienta, aby podwoić liczbę nowych znaków przez dodanie następujących elementów do javascript po dodaniu jquery.validate.js. Spowoduje to dopasowanie metod po stronie serwera i po stronie klienta, pozwalając ci użyć atrybutu StringLength (zakładam, że problem z StringLength polegał na tym, że metody sprawdzania poprawności serwera i klienta różniły się).

$.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

Podział nie zadziałał dla mnie. Miałem problem z końcowymi podziałami linii, które nie zostały policzone przy użyciu Twojej metody. Użyłem tego zamiast: '// zamienia znaki nowej linii na 2 spacje, aby liczba pasowała do serwera. zmieniony replaceValue = value.replace (/ (\ n)/gm, ""); return replaceValue.length; ' Uwaga: blok kodu w jakiś sposób pokazuje tylko jedno miejsce, w którym powinny znajdować się dwa. – Ben

5

Po zrobieniu przyjrzeć roztworu przez @Chris, stwierdziliśmy, że mogłoby to spowodować nieskończoną pętlę dla jakiejkolwiek kontroli innej niż textarea z atrybutem @maxlength.
Ponadto odkryłem, że używanie value (= wartość textarea przekazywanego do walidatora) ma już przerwanie linii wiodącej i końcowej, co oznacza, że ​​operacja bazy danych nadal nie powiodła się, gdy próbowano zapisać tekst zawierający te linie podziału.
Więc tu jest moje rozwiązanie:

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

Testowałem to w Chrome i kilku wersjach IE i to działało dobrze dla mnie.

Powiązane problemy