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

Validation for MetadataType using Custom validation attribute #50584

Open smiljanj opened 1 year ago

smiljanj commented 1 year ago

Is there an existing issue for this?

Describe the bug

Hi,

can you please help me resolve a problem with Custom validation attribute in Blazor Server? Problem is that I have defined a ViewModel class that inherits from class "Certificates" (record in table; scaffolded) and I define MetaDataClass to specify Validation attributes (standard + custom ValidDebelina).

namespace QMblazor.ViewModels
{
       [MetadataType(typeof(CertificateMetadata))]
       public class CertificateEditVM : Certificates
       {
        public bool NewRecord { get; set; }
        public string? xCertStatusDesc { get; set; } 
    }
}
public class CertificateMetadata
{
     [Required]
     [StringLength(100)]
     public string AAA { get; set; }

    [Required]
    [StringLength(20)]
    public string BBB { get; set; }

    [Required]
    public DateTime CCC { get; set; }

    [Required]
    **[ValidDebelina]**
        public double? RezDebelina { get; set; }
}
public partial class Certificates
{
    [Key]
    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string AAA { get; set; }

    [Required]
    [StringLength(20)]
    public string BBB { get; set; }

    [Column(TypeName = "datetime")]
    public DateTime CCC { get; set; }

    [Column("Rez_Debelina")]
    public double? RezDebelina { get; set; }
}
    public class ValidDebelina : ValidationAttribute
    {
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var certificate = (Certificates)validationContext.ObjectInstance;

                if (certificate.RezDebelina == null)
                    return new ValidationResult("Proprety DebelinaRez is missing entry.", new[] { validationContext.MemberName});
                else
                    return ValidationResult.Success;
        }
    }

Problem is that EditForm will validate properties AAA, BBB and CCC, but it will not fire on property RezDebelina (attribute "ValidDebelina") when used inside MetaData class. If I decorate property RezDebelina in original/scaffolded class Certificates, it fires ok (I debug and it executes code for Custome attribue). Is it possible that MetaDataType approach for validation works only with "default" types (string, int, dateTime...) and not with Custome ones?

I used exact same code in .NET MVC5 and it works ok. I'm currently using .Net7 (AspNet core 7.08) + Blazor-server.

Many tnx for any kind of info.

BR, Smiljan

Expected Behavior

MetaDataType should also execute code inside custom attribute definition (code).

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

7.0.102

Anything else?

AspNetCore 7.0.8. VS 2022 17.4.4

.NET SDK: Version: 7.0.102 Commit: 4bbdd14480

Runtime Environment: OS Name: Windows OS Version: 10.0.19044 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\7.0.102\

Host: Version: 7.0.2 Architecture: x64 Commit: d037e070eb

.NET SDKs installed: 5.0.404 [C:\Program Files\dotnet\sdk] 7.0.102 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.All 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found: x86 [C:\Program Files (x86)\dotnet] registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables: Not set

global.json file: Not found

Learn more: https://aka.ms/dotnet/info

Download .NET: https://aka.ms/dotnet/download

javiercn commented 1 year ago

@smiljanj thanks for contacting us.

I don't believe blazor supports MetadataType. You need to put the attributes directly on the type or if that's not possible, create a new type and map your data to it.

smiljanj commented 1 year ago

@javiercn tnx for reply. Blazor supports MetadataType. I'm just having problems with custome attribute validation (it validates standard attribute types like int, string etc. with no problem).

javiercn commented 1 year ago

@smiljanj thansks for the additional details. This might be a question for the runtime folks then