Jak zmienić walidację wiadomości 'data-Val-number' W MVC podczas generowania jej przez @ Html helper

Przyjmij ten model:

Public Class Detail
    ...
    <DisplayName("Custom DisplayName")>
    <Required(ErrorMessage:="Custom ErrorMessage")>
    Public Property PercentChange As Integer
    ...
end class

I widok:

@Html.TextBoxFor(Function(m) m.PercentChange)

Będzie kontynuował ten html:

   <input data-val="true" 
    data-val-number="The field 'Custom DisplayName' must be a number." 
    data-val-required="Custom ErrorMessage"     
    id="PercentChange" 
    name="PercentChange" type="text" value="0" />

Chcę dostosować komunikat o błędzie data-val-number, który, jak sądzę, został wygenerowany, ponieważ PercentChange jest Integer. Szukałem takiego atrybutu, aby go zmienić, range lub cokolwiek pokrewnego nie działa.
Wiem, że istnieje szansa na edycję samego pliku JS lub nadpisanie go po stronie klienta. Chcę zmienić komunikat o błędzie data-val-number tak jak inne na serwerze bok.

Author: Leniel Maccaferri, 2011-01-28

14 answers

To nie będzie łatwe. Domyślna wiadomość jest przechowywana jako zasób wbudowany do zestawu System.Web.Mvc, a metoda, która jest pobierana, jest prywatną statyczną metodą wewnętrznej zamkniętej klasy wewnętrznej (System.Web.Mvc.ClientDataTypeModelValidatorProvider+NumericModelValidator.MakeErrorString). To tak, jakby facet z Microsoftu kodujący to ukrywał ściśle tajne: -)

Możesz spojrzeć na następujący blog post , który opisuje możliwe rozwiązanie. Zasadniczo musisz zastąpić istniejący ClientDataTypeModelValidatorProvider z niestandardowym jeden.

Jeśli nie podoba Ci się kodowanie hardcore, które będziesz musiał wykonać, Możesz również zastąpić tę wartość całkowitą wewnątrz modelu widoku ciągiem znaków i mieć na nim Niestandardowy atrybut walidacji, który wykonałby parsowanie i dostarczyłby niestandardowy komunikat o błędzie (który może być nawet zlokalizowany).

 39
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-13 16:25:44

Możesz nadpisać wiadomość, podając atrybut data-Val-number podczas renderowania pola. Spowoduje to nadpisanie domyślnej wiadomości. Działa to przynajmniej z MVC 4.

@Html.EditorFor (model = > model.MyNumberField, new { data_val_number= " Podaj liczbę całkowitą, koleś!" })

Pamiętaj, że musisz użyć podkreślenia w nazwie atrybutu, aby Razor zaakceptował twój atrybut.

 77
Author: HenningJ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-18 11:07:50

To co musisz zrobić to:

Dodaj następujący kod wewnątrz Application_Start() w Global.asax:

 ClientDataTypeModelValidatorProvider.ResourceClassKey = "Messages";
 DefaultModelBinder.ResourceClassKey = "Messages";

Kliknij prawym przyciskiem myszy ASP.NET projekt MVC w VS. Select Add => Add ASP.NET Folder => App_GlobalResources.

Dodaj .resx plik o nazwie Messages.resx do tego folderu.

Dodaj te zasoby w pliku .resx:

FieldMustBeDate        The field {0} must be a date.
FieldMustBeNumeric     The field {0} must be a number.
PropertyValueInvalid   The value '{0}' is not valid for {1}.
PropertyValueRequired  A value is required.

Zmień wartość FieldMustBeNumeric jak chcesz... :)

Jesteś skończony.

Sprawdź ten post, aby uzyskać więcej szczegółów:

Lokalizowanie domyślnych komunikatów o błędach w ASP.NET MVC i WebForms

 52
Author: Leniel Maccaferri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-12 12:29:03

Jako alternatywny sposób obejścia tego problemu, zastosowałem atrybut RegularExpression, aby złapać nieprawidłowy wpis i ustawić tam moją wiadomość:

[RegularExpression(@"[0-9]*$", ErrorMessage = "Please enter a valid number ")]

To trochę hack, ale wydawało się to lepsze niż złożoność innych rozwiązań przedstawionych, przynajmniej w mojej konkretnej sytuacji.

EDIT: to działało dobrze w MVC3, ale wydaje się, że mogą być lepsze rozwiązania dla MVC4+.

 23
Author: Matthew Nichols,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-15 15:13:13

Z tej książki o MVC 3, którą mam. Wszystko co musisz zrobić to:

public class ClientNumberValidatorProvider : ClientDataTypeModelValidatorProvider 
{ 
   public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, 
                                                          ControllerContext context) 
   { 
       bool isNumericField = base.GetValidators(metadata, context).Any(); 
       if (isNumericField) 
           yield return new ClientSideNumberValidator(metadata, context); 
   } 
} 

public class ClientSideNumberValidator : ModelValidator 
{ 
  public ClientSideNumberValidator(ModelMetadata metadata,  
      ControllerContext controllerContext) : base(metadata, controllerContext) { } 

  public override IEnumerable<ModelValidationResult> Validate(object container) 
  { 
     yield break; // Do nothing for server-side validation 
  } 

  public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
  { 
     yield return new ModelClientValidationRule { 
        ValidationType = "number", 
        ErrorMessage = string.Format(CultureInfo.CurrentCulture,  
                                     ValidationMessages.MustBeNumber,  
                                     Metadata.GetDisplayName()) 
        }; 
  } 
} 

protected void Application_Start() 
{ 
    // Leave the rest of this method unchanged 

    var existingProvider = ModelValidatorProviders.Providers 
        .Single(x => x is ClientDataTypeModelValidatorProvider); 
    ModelValidatorProviders.Providers.Remove(existingProvider); 
    ModelValidatorProviders.Providers.Add(new ClientNumberValidatorProvider()); 
} 

Zwróć uwagę na to, jak generowany jest błąd, określ bieżącą kulturę, a zlokalizowana wiadomość zostanie wyodrębniona z ValidationMessages (tutaj należy podać specyfikę kultury).plik zasobów resx. Jeśli tego nie potrzebujesz, po prostu zastąp go własną wiadomością.

 11
Author: Denis Valeev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-28 10:50:48

Oto inne rozwiązanie, które zmienia stronę Klienta wiadomości bez zmiany źródła MVC3. Szczegóły w tym wpisie na blogu:

Https://greenicicle.wordpress.com/2011/02/28/fixing-non-localizable-validation-messages-with-javascript/

W skrócie to co musisz zrobić to dołączyć następujący skrypt po załadowaniu jQuery validation oraz odpowiedni plik lokalizacyjny .

(function ($) {
    // Walk through the adapters that connect unobstrusive validation to jQuery.validate.
    // Look for all adapters that perform number validation
    $.each($.validator.unobtrusive.adapters, function () {
        if (this.name === "number") {
            // Get the method called by the adapter, and replace it with one 
            // that changes the message to the jQuery.validate default message
            // that can be globalized. If that string contains a {0} placeholder, 
            // it is replaced by the field name.
            var baseAdapt = this.adapt;
            this.adapt = function (options) {
                var fieldName = new RegExp("The field (.+) must be a number").exec(options.message)[1];
                options.message = $.validator.format($.validator.messages.number, fieldName);
                baseAdapt(options);
            };
        }
    });
} (jQuery));
 7
Author: Phil Hale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-21 10:34:27

Możesz ustawić ResourceKey klasy ClientDataTypeModelValidatorProvider na nazwę globalnego zasobu, który zawiera klucz FieldMustBeNumeric, aby zastąpić komunikat błędu walidacji MVC numeru niestandardowym Komunikatem. Również kluczem Komunikatu o błędzie walidacji daty jest FieldMustBeDate.

ClientDataTypeModelValidatorProvider.ResourceKey="MyResources"; // MyResource is my global resource

Zobacz tutaj aby uzyskać więcej informacji o tym, jak dodać plik MyResources.resx do swojego projektu:

 5
Author: reza taroosheh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-12 08:28:05

Oto inne rozwiązanie w pure js, które działa, jeśli chcesz określić wiadomości globalnie, a nie niestandardowe wiadomości dla każdego elementu.

Kluczem jest to, że wiadomości walidacyjne są ustawiane za pomocą jquery.validation.unobtrusive.js za pomocą atrybutu data-val-xxx na każdym elemencie, więc wszystko, co musisz zrobić, to zastąpić te wiadomości, zanim biblioteka ich użyje, jest to trochę brudne, ale chciałem tylko wykonać pracę i szybko, więc tutaj idzie do walidacji typu numer:

    $('[data-val-number]').each(function () {
    var el = $(this);
    var orig = el.data('val-number');

    var fieldName = orig.replace('The field ', '');
    fieldName = fieldName.replace(' must be a number.', '');

    el.attr('data-val-number', fieldName + ' باید عددی باشد')
});

Dobrą rzeczą jest to, że nie wymaga kompilacji i można go łatwo później rozszerzyć, choć nie solidne, ale szybko.

 3
Author: mohas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-29 12:40:37

Zobacz też:

Kompletny przewodnik po walidacji w ASP.NET MVC 3-Część 2

Główne części artykułu następują (kopiuj-wklej).

Istnieją cztery różne części tworzenia w pełni funkcjonalnego walidatora niestandardowego, który działa zarówno na kliencie, jak i na serwerze. Najpierw podklasujemy ValidationAttribute i dodajemy naszą logikę walidacji po stronie serwera. Następnie implementujemy IClientValidatable na naszym atrybutie, aby umożliwić przekazywanie atrybutów HTML5 data-* do klienta. Po trzecie, piszemy niestandardowa funkcja JavaScript wykonująca walidację na kliencie. Na koniec tworzymy adapter, aby przekształcić atrybuty HTML5 w format, który nasza niestandardowa funkcja może zrozumieć. Chociaż brzmi to jak dużo pracy, gdy zaczniesz, okaże się to stosunkowo proste.

Subclassing ValidationAttribute

W tym przykładzie napiszemy walidator NotEqualTo, który po prostu sprawdza, czy wartość jednej właściwości nie jest równa wartości innego.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class NotEqualToAttribute : ValidationAttribute
{
    private const string DefaultErrorMessage = "{0} cannot be the same as {1}.";

    public string OtherProperty { get; private set; }

    public NotEqualToAttribute(string otherProperty)
        : base(DefaultErrorMessage)
    {
        if (string.IsNullOrEmpty(otherProperty))
        {
            throw new ArgumentNullException("otherProperty");
        }

        OtherProperty = otherProperty;
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(ErrorMessageString, name, OtherProperty);
    }

    protected override ValidationResult IsValid(object value, 
        ValidationContext validationContext)
    {
        if (value != null)
        {
            var otherProperty = validationContext.ObjectInstance.GetType()
                .GetProperty(OtherProperty);

            var otherPropertyValue = otherProperty
                .GetValue(validationContext.ObjectInstance, null);

            if (value.Equals(otherPropertyValue))
            {
                return new ValidationResult(
                    FormatErrorMessage(validationContext.DisplayName));
            }
        }
    return ValidationResult.Success;
    }        
}

Dodaj nowy atrybut do właściwości password Modela RegisterModel i uruchom aplikację.

[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
[NotEqualTo("UserName")]
public string Password { get; set; }
...

Implementacja IClientValidatable

ASP.NET MVC 2 miał mechanizm dodawania walidacji po stronie klienta, ale nie był zbyt ładny. Na szczęście w MVC 3 rzeczy się poprawiły i proces jest teraz dość trywialny i na szczęście nie wymaga zmiany Global.asax jak w poprzedniej wersji.

Pierwszym krokiem jest dla Twojego niestandardowego atrybutu walidacji, aby zaimplementować IClientValidatable. Jest to prosty, jeden interfejs metody:

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
    ModelMetadata metadata,
    ControllerContext context)
{
    var clientValidationRule = new ModelClientValidationRule()
    {
        ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
        ValidationType = "notequalto"
    };

    clientValidationRule.ValidationParameters.Add("otherproperty", OtherProperty);

    return new[] { clientValidationRule };
}

Jeśli uruchomisz aplikację teraz i przejrzysz źródło, zobaczysz, że kod HTML wprowadzający hasło zawiera teraz twoje atrybuty danych notequalto:

<div class="editor-field">
    <input data-val="true" data-val-notequalto="Password cannot be the same as UserName." 
    data-val-notequalto-otherproperty="UserName" 
    data-val-regex="Weak password detected." 
    data-val-regex-pattern="^(?!password$)(?!12345$).*" 
    data-val-required="The Password field is required." 
    id="Password" name="Password" type="password" />
    <span class="hint">Enter your password here</span>
    <span class="field-validation-valid" data-valmsg-for="Password" 
    data-valmsg-replace="true"></span>
</div>

Tworzenie niestandardowej funkcji jQuery validate

Cały ten kod najlepiej umieścić w osobnym pliku JavaScript.

(function ($) {
    $.validator.addMethod("notequalto", function (value, element, params) {
        if (!this.optional(element)) {
            var otherProp = $('#' + params);
            return (otherProp.val() != 
        }
    return true;
});

$.validator.unobtrusive.adapters.addSingleVal("notequalto", "otherproperty");

}(jQuery));

W zależności od wymagań walidacji, możesz znaleźć to jQuery.biblioteka walidacji zawiera już kod potrzebny do samej walidacji. W jquery jest wiele walidatorów.zweryfikuj, które nie zostały zaimplementowane lub zmapowane do adnotacji do danych, więc jeśli spełniają Twoje potrzeby, to wszystko, co musisz napisać w javascript, to adapter lub nawet połączenie z wbudowanym adapterem, które może być tak małe, jak pojedyncza linia. Zajrzyj do jquery./ align = "left" / js , aby dowiedzieć się, co jest dostępne.

Korzystanie z istniejącego jquery./ align = "left" / Adapter unobtrusive

Zadaniem adaptera jest odczytanie atrybutów HTML5 data-* na elemencie formularza i przekształcenie tych danych w Formularz, który może być zrozumiały przez jquery.Walidacja i niestandardowa funkcja walidacji. Nie musisz jednak wykonywać całej pracy samodzielnie, a w wielu przypadkach możesz zadzwonić do wbudowanego adaptera. jquery./ align = "left" / dyskretny deklaruje trzy wbudowane adaptery, które mogą być używane w większości sytuacji. Te są:

jQuery.validator.unobtrusive.adapters.addBool - used when your validator does not need any additional data.
jQuery.validator.unobtrusive.adapters.addSingleVal - used when your validator takes in one piece of additional data.
jQuery.validator.unobtrusive.adapters.addMinMax - used when your validator deals with minimum and maximum values such as range or string length.

Jeśli walidator nie pasuje do jednej z tych kategorii, musisz napisać własny adapter przy użyciu metody jQuery.validator.unobtrusive.adapters.add. To nie jest tak trudne, jak się wydaje i zobaczymy przykład w dalszej części artykułu.

Używamy metody addSingleVal, przekazując nazwę adaptera i nazwę pojedynczej wartości, którą chcemy przekazać. Jeśli nazwa funkcji walidacji różni się od adaptera, można przekazać trzeci parametr (ruleName):

jQuery.validator.unobtrusive.adapters.addSingleVal("notequalto", "otherproperty", "mynotequaltofunction");

W tym momencie nasz walidator jest kompletny.

Aby lepiej zrozumieć, zapoznaj się z samym artykułem , który zawiera bardziej szczegółowy opis i bardziej złożony przykład.

HTH.

 2
Author: Kamran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-03 13:35:29

Właśnie to zrobiłem, a następnie użyłem wyrażenia regex:

$(document).ready(function () {
    $.validator.methods.number = function (e) {
        return true;
    };
});


[RegularExpression(@"^[0-9\.]*$", ErrorMessage = "Invalid Amount")]
public decimal? Amount { get; set; }
 1
Author: Rob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-19 12:22:03

Albo po prostu możesz to zrobić.

@Html.ValidationMessageFor(m => m.PercentChange, "Custom Message: Input value must be a number"), new { @style = "display:none" })
Mam nadzieję, że to pomoże.
 1
Author: Edward Disi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-26 22:27:49

I make this putting this on my view

@Html.DropDownListFor(m => m.BenefNamePos, Model.Options, new { onchange = "changePosition(this);", @class="form-control", data_val_number = "This is my custom message" })
 1
Author: Fernando Campos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-14 14:41:25

Mam ten problem w KendoGrid, używam skryptu na końcu widoku, aby nadpisać data-val-number:

@(Html.Kendo().Grid<Test.ViewModel>(Model)
  .Name("listado")
  ...
  .Columns(columns =>
    {
        columns.Bound("idElementColumn").Filterable(false);
    ...
    }

A przynajmniej na końcu widoku umieściłem:

<script type="text/javascript">
        $("#listado").on("click", function (e) {
            $(".k-grid #idElementColumn").attr('data-val-number', 'Ingrese un número.');
        });    
</script>
 0
Author: Hernaldo Gonzalez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-06 17:01:46

Prostą metodą jest, użyj wiadomości zmiany dataanotation na ViewModel:

[Required(ErrorMessage ="الزامی")]
[StringLength(maximumLength:50,MinimumLength =2)]
[Display(Name = "نام")]
public string FirstName { get; set; }
 0
Author: Omid Marofpor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-10 22:12:30