dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.36k stars 9.99k forks source link

Custom DataAnnotation ValidationAttribute error message is not showing #15301

Closed PKYADAV closed 4 years ago

PKYADAV commented 5 years ago

Model Definition:

    [DbRequired]
    [Display(Name = "USER NAME", Prompt = "ENTER USER NAME")]
    public string User_Name
    {
        get { return GetValue(() => User_Name); }
        set { SetValue(() => User_Name, value); }
    }

    [Display(Name = "PASSWORD", Prompt = "ENTER PASSWORD")]
    [DataType(DataType.Password)]
    [DbRequired]
    public string User_Password
    {
        get { return GetValue(() => User_Password); }
        set { SetValue(() => User_Password, value); }
    }

ValidationAttribute:

public class DbRequired : RequiredAttribute { DataContext db; protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if ((value == null || value.ToString() == string.Empty || value.ToString() == "0")) { return new ValidationResult("USER NAME IS REQUIRED FIELD !"); } else { return ValidationResult.Success; } } }

When using builtin Required then working fine but when overriding RequiredAttribute then error message not displayed: image

PKYADAV commented 5 years ago

@PKYADAV Did you find the solution to this? Running into the same issue.

Yes, just pass the member name in validation context in below line: return new ValidationResult("USER NAME IS REQUIRED FIELD !");

Please try and let me know, if any issue. Will post source code reference.

pelhamrj commented 5 years ago

@PKYADAV Thank you for the help! I ended up ditching DataAnnotations out of frustration with custom attributes, and am now using FluentValidation. I appreciate such a quick response! 😄

PKYADAV commented 5 years ago

Hii @pelhamrj, If your requirement is static then Fluent Validation is best option but if your requirement is dynamic then you need to write custom validation attribute.

dev-masih commented 5 years ago

@PKYADAV Did you find the solution to this? Running into the same issue.

Yes, just pass the member name in validation context in below line: return new ValidationResult("USER NAME IS REQUIRED FIELD !");

Please try and let me know, if any issue. Will post source code reference.

this is works for me but why? in asp.net projects this wasn't needed.

PKYADAV commented 5 years ago

Can you share more information and scenario on that you want to achieve?

dev-masih commented 5 years ago

Can you share more information and scenario on that you want to achieve?

well, in asp.net project when I used custom data annotation attributes, I didn't need to explicitly put input name in returning of ValidationResult but now in blazor projects, if I don't do this, custom annotations won't work

cveld commented 5 years ago

At least in Blazor Server 3.0 we can confirm the same behavior that @dev-masih is reporting. We also find this confusing behavior. Ideally the system should be defaulting to the field that the validator is attached to if an explicit list of one or more fields is omitted.

jadennis commented 5 years ago

We were trying to use custom validation in Blazor Server 3.0. We were not having any success until we found this issue. Just wanted to share a clear example of what works for us in case it helps anyone.

return new ValidationResult("REQUIRED FIELD !", new [] { validationContext.MemberName });

pranavkm commented 4 years ago

@PKYADAV, copying my comment from https://github.com/aspnet/AspNetCore/issues/10643#issuecomment-543909748

As noted in https://github.com/aspnet/AspNetCore/issues/10643#issuecomment-520236208, on a form submit Blazor's DataAnnotationsValidator fails to record validation results that are not associated with a member. CompareAttribute does this which results in the buggy behavior you're seeing here.

In 3.1, we're doing a couple of things to address this:

1) Validation results without members now get associated with the model instance. In addition we've added support to ValidationSummary to print error messages that are specifically associating with the model. You should be able to do something along the lines of

<EditForm Model="myModel" OnValidSubmit="OnSubmit">
    <DataAnnotationsValidator />
    <InputText Name="Password" /> <ValidationMessage For=@(() => myModel.Password)" />
    <InputText Name="ConfirmPassword" /> <ValidationMessage For=@(() => myModel.ConfirmPassword)" />    

    <ValidationSummary Model="myModel" />
    <button class="btn btn-danger" type="submit">Submit</button>
</EditForm>

The ValidationSummary would additionally display messages produced from models implementing IValidatableObject or using custom ValidationAttribute \ CustomValidationAttribute.

  1. In addition, for the 3.1.0-preview2 release, we plan on introducing an experimental package - Microsoft.AspNetCore.Components.DataAnnotations.Validation - with an ComparePropertyAttribute that behaves like a CompareAttribute but produces a valid MemberName. It should be a drop in replacement to CompareAttribute. Users in 3.0 should be able to copy the type in to their app to resolve the error they're seeing here. Here's the source: https://github.com/aspnet/AspNetCore/blob/c298c94fe1113b64474a3d5fcdef487f02c74991/src/Components/Blazor/Validation/src/ComparePropertyAttribute.cs

This package is marked experimental since our plan is to roll these changes in to CoreFx as part of the 5.0 milestone. Hope this helps.