jQuery проверяет текстовую ошибку максимальной длины - PullRequest
14 голосов
/ 03 декабря 2010

Я использую jQuery.validate v 1.6.0 для проверки своих форм.

Одно из полей моей базы данных ограничено 1000 символов.Я добавил валидацию к соответствующей текстовой области следующим образом:

В заголовке моей страницы я добавляю

$('form.validate').validate();

Внутри моей страницы я заявляю:

<form method="post" class="validate" action="Save">
    <textarea name="description" minlength="15" maxlength="1000" id="description" class="required"></textarea>
    <input type="submit" value="Save">    
</form>

Проблема, с которой я сталкиваюсь, заключается в том, что jQuery, похоже, подсчитывает количество символов, участвующих в «новой строке», по-другому, как моя база данных.

Когда я набираю ровно 1000 символов без новых строк, все идет хорошовалидация работает.Если я наберу 1000 символов с некоторыми новыми строками, jQuery позволит выполнить POST, но моя база данных откажет в вставке / обновлении, потому что данные слишком велики.

Любые подсказки приветствуются.

Ответы [ 7 ]

5 голосов
/ 11 октября 2012

Я решил эту проблему с помощью jQuery Validate 1.9.Потому что я использую ASP.NET MVC 3 и C # на сервере разрывы строк были "\ r \ n" на сервере, но "\ n" на клиенте.Когда я проверял свою текстовую область на клиенте, проверка не заканчивалась ошибкой, потому что "\ n" просто считается одним символом, но когда текст прошел проверку на сервере, где разрывы строк равны "\ r \ n", проверка не удалась.

Моя задача заключалась в том, чтобы переопределить метод проверки jQuery "rangelengt", потому что у меня также определена минимальная длина:

$.validator.addMethod('rangelength', function (value, element) {
        var maxlen = parseInt($(element).attr('data-val-length-max'));
        if (maxlen > 0) {
            var remaining = (maxlen - (parseInt($(element).val().replace(/(\r\n|\n|\r)/gm, '\r\n').length)));
            if (remaining < 0) {
                return false;
            }
        }

        return true;
    });

Итак, этот код на самом деле делает, чтобы получить значение maxlength, а затемполучить значение из элемента, а затем он заменяет все символы "\ n" на "\ r \ n", чтобы получить то же количество символов, что и сервер.

2 голосов
/ 30 октября 2012

Я расширяю Робин Риддерхолт решение, теперь мы можем отнести maxlen к валидатору

$.validator.addMethod('extMaxLength', function (value, element, maxlen){
            if (maxlen > 0) {
                var remaining = (maxlen - (parseInt($(element).val().replace(/(\r\n|\n|\r)/gm, '\n').length, 10)));
                if (remaining < 0) {
                    return false;
                }
            }
            return true;
        });
2 голосов
/ 14 марта 2012

Я также применил подход на стороне сервера, как это сделал Джон Бубриски, но реализовал его в ASP.NET MVC как расширение DefaultModelBinder, так что все действия контроллера сразу принесут пользу:

public class NewlinesNormalizingModelBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);

        // Note: if desired, one could restrict the conversion to properties decorated with [StringLength]:
        // && propertyDescriptor.Attributes.OfType<StringLengthAttribute>().Any()
        if (propertyDescriptor.PropertyType == typeof(string))
        {
            var originalString = propertyDescriptor.GetValue(bindingContext.Model) as string;
            if (!string.IsNullOrEmpty(originalString))
            {
                var stringWithNormalizedNewlines = originalString.Replace("\r\n", "\n");
                propertyDescriptor.SetValue(bindingContext.Model, stringWithNormalizedNewlines);
            }
        }
    }
}

Затем при запуске приложения:

ModelBinders.Binders.DefaultBinder = new NewlinesNormalizingModelBinder();
2 голосов
/ 29 ноября 2011

Хотя это не решение на стороне клиента, я смог решить проблему на стороне сервера.

Я в основном убираю "лишние" символы, которые являются символами "\ r". Я предполагаю, что они не учитываются в длину строки в браузере, или они объединяются в один с символами "\ n".

В моем случае ASP.NET MVC с C #:

[HttpPost]
public ActionResult SetComment(int id, string comment)
{
    // Yep, the browser can insert newlines as "\r\n" which overflows the allowed number of characters!
    comment = comment.Replace("\r", "");

    // More code...
}
1 голос
/ 14 января 2012

Я столкнулся с такой же проблемой.это связано с тем, что в javascript field.length будет возвращать количество символов, но один символ может использовать 2 байта для хранения информации.

Моя проблема заключалась в том, что поле VARCHAR2 в БД может хранить только 4000 байтовинформации, или 2000 персонажей.Мы легко запутываемся и думаем, что можем хранить 4000 символов в таких полях.

Я думаю, что в вашем случае это поле не ограничено 1000 символами, а 1000 байтами, что должно быть одинаковым только для вас.«стандартные символы», которые используют один байт информации, поэтому я бы уменьшил ограничение до 2000 байт и оставил проверку javascript до 1000 символов.Затем, конечно, я пошел бы против предыдущего ответа и выполнил проверку на количество символов на стороне сервера.

Конечно, у вас есть другие решения, в моем случае, например (хотя я не использовал Jquery)Я настроил счетчик символов, чтобы он дважды учитывал каждый специальный символ (эти проблемы влияют на символы новой строки, но также и на ударения ....)

0 голосов
/ 24 февраля 2015

Я бы предложил просто улучшить решение Якуба Березанского .

Лично я нахожу его идею (как правило, обрабатывать это на стороне сервера) очень хорошей.

Только одна проблема с его примером кода может заключаться в том, что модель в конечном итоге уже недействительна во время переопределения метода BindProperty - если это вызвано только длиной этого поля, которое мы там исправляем.

Поэтому мое предложение по улучшению этого решения состоит в том, чтобы применить ту же логику, которая уже используется в переопределении GetPropertyValue, которое выполняется до проверки:

public class NewlinesNormalizingModelBinder : DefaultModelBinder
{
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
    {
        // Note: if desired, one could restrict the conversion to properties decorated with [StringLength]:
        // && propertyDescriptor.Attributes.OfType<StringLengthAttribute>().Any()
        if (propertyDescriptor.PropertyType == typeof(string))
        {
            string originalString = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;

            if (!string.IsNullOrEmpty(originalString)) return originalString.Replace("\r\n", "\n");
        }

        return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
    }
}
0 голосов
/ 24 декабря 2010

Удалите проверку сервера и оставьте только проверку на стороне клиента. В html новая строка = 3 символа В базе данных новая строка = 1 символ Так что вы должны держать только один раз. или измените настройку db char

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...