0

У меня есть приложение ASP.NET MVC5 и это мой ViewModel:ASP.NET MVC вопрос проверки на стороне клиента для функции диапазона

[RegularExpression("[0-9]+(,[0-9]+)*"] 
    [Range(1, double.MaxValue, ErrorMessage = "value is not correct")] 
    [Required] 
    [DisplayFormat(DataFormatString = "{0:0,0}", ApplyFormatInEditMode = true, HtmlEncode = true)] 
    public double? Amount { get; set; } 

и мое мнение:

<div class="col-sm-8"> 
    @Html.EditorFor(m => m.Amount, new { @class = "form-control font-num numbers", maxlength = "10" }) 
    @Html.ValidationMessageFor(m => m.Amount, "", new { @class = "text-danger" }) 
</div> 

Единственная известная вещь это номера формата I с использованием разделителя запятой каждые три цифры в моем представлении.

Например: 123456789 => 123456789

Я знаю, что я должен использовать пользовательские модели связующие для проверки на стороне сервера и переопределить реализацию по умолчанию из файла jquery.validate.js для диапазона() и число() функции.

Так я следующим образом:

public class DoubleModelBinder : IModelBinder 
{ 
    /// <summary> 
    /// Binds the value to the model. 
    /// </summary> 
    /// <param name="controllerContext">The current controller context.</param> 
    /// <param name="bindingContext">The binding context.</param> 
    /// <returns>The new model.</returns> 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var culture = GetUserCulture(controllerContext); 

     string value = bindingContext.ValueProvider 
          .GetValue(bindingContext.ModelName) 
          .ConvertTo(typeof(string)) as string; 

     double result = 0; 
     double.TryParse(value, NumberStyles.Any, culture, out result); 

     return result; 
    } 

    /// <summary> 
    /// Gets the culture used for formatting, based on the user's input language. 
    /// </summary> 
    /// <param name="context">The controller context.</param> 
    /// <returns>An instance of <see cref="CultureInfo" />.</returns> 
    public CultureInfo GetUserCulture(ControllerContext context) 
    { 
     var request = context.HttpContext.Request; 
     if (request.UserLanguages == null || request.UserLanguages.Length == 0) 
      return CultureInfo.CurrentUICulture; 

     return new CultureInfo(request.UserLanguages[0]); 
    } 
} 

И стороне клиента проверки:

$.validator.methods.range = function (value, element, param) { 
var globalizedValue = value.replace(",", ""); 
return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);} 

$.validator.methods.number = function (value, element) { 
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);} 

Проверка на стороне сервера работает хорошо, но проверка на стороне клиента не работает правильно, и я всегда получить «значение неверно». Если я игнорирую [Range (1, double.MaxValue, ErrorMessage = "значение неверно")], он работает хорошо, но пользователь может ввести нуль для этого поля. Что не так в моей проверке на стороне клиента?

ответ

0

После того, как проводить много времени и отслеживания функции диапазона(), наконец, я обнаружил, что следует использовать:

var globalizedValue = value.replace(new RegExp(",", "g"), ""); 

Вместо

var globalizedValue = value.replace(",", ""); 

Потому что у меня более одной запятой (например: 123 456 789), а поведение по умолчанию .replace() - заменить только первое совпадение.

Моя ошибка была Я использовал решение в блоге this, в то время как моя проблема была иной. Я использую запятую как разделитель каждые три цифры, а не как десятичный разделитель. Поэтому у меня есть более одной запятой, и метод replace() по умолчанию не подходит. Фактически, RegExp(",", "g") заменяет все вхождения.

Смежные вопросы