user3232760
user3232760

Reputation: 13

Change the default error message in the model state binder - not working

This (in ASP.NET Core 3.1) is how my property looks like in the class:

[BindProperty]
[Required(ErrorMessage = "Enter the valid amount")]
[ValidDecimal(ErrorMessage = "Enter the amount correctly")]
public decimal? QuoteAmountTotal { get; set; }

This is the code for custom ValidDecimal value is:

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class ValidDecimalAttribute : ValidationAttribute{
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
    if (value == null || value.ToString().Length == 0)
    {
        return ValidationResult.Success;
    }

    return decimal.TryParse(value.ToString(), out _) ? ValidationResult.Success : new ValidationResult(ErrorMessage);
}

I am entering a value in this field with space or alpha numeric. For example 2 0 0 0.

However, it displays default ASP.NET Core MVC error instead of my custom error which is

The value '2 0 0 0' is not valid for QuoteAmountTotal.

This is AttemptedvalueisInvalidAccessor:

enter image description here

I need to display my custom error message instead of default ASP.NET Core MVC error message, which is not displaying in this case.

Upvotes: 0

Views: 1478

Answers (1)

Ruikai Feng
Ruikai Feng

Reputation: 11621

If you put a break point on IsValid method ,when you debug,you'll find the method is never excuted

as the doc indicates:

Model state represents errors that come from two subsystems: model binding and model validation. Errors that originate from model binding are generally data conversion errors.Model validation occurs after model binding and reports errors where data doesn't conform to business rules.

UpDate: You could try to replace the model binder with your customer model binder,I tried as below:

public class SomeEntityBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }



           var modelName = bindingContext.ModelName;
            // Try to fetch the value of the argument by name
            var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);



           if (valueProviderResult == ValueProviderResult.None)
            {
                return Task.CompletedTask;
            }



           bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
            var value = valueProviderResult.FirstValue;



           // Check if the argument value is null or empty
            if (string.IsNullOrEmpty(value))
            {
                return Task.CompletedTask;
            }
            
            if (!decimal.TryParse(value, out var QuoteAmountTotal))
            {
                // Non-decimal arguments result in model state errors
                bindingContext.ModelState.TryAddModelError(modelName,"Enter the amount correctly");



               return Task.CompletedTask;
            }
            bindingContext.Result = ModelBindingResult.Success(QuoteAmountTotal);
            return Task.CompletedTask;
        }
    }

in model:

[ModelBinder (typeof(SomeEntityBinder))]
public decimal QuoteAmountTotal { get; set; }

Result:

enter image description here

Upvotes: 0

Related Questions