Recently started to migrate a kinda big project done in dot.net core 3.1 MVC to use Blazor, the new (not so new at the time of creating this post) framework from Microsoft for creating Single Page Applications (SPA).

All went great, maybe in a separate post will explain how did I manage to have the Asp.NET Core Web API, Asp.NET Core MVC, Blazor sites inside MVC and Blazor Webassembly in the the same project.

The first issue I encounter was that the most that functional System.ComponentModel.DataAnnotations didn’t work any more in Blazor sites, for some reason, when it tries to validate the DataAnnotations it just ignore it. I use a partial class to assign it, because everytime that the Scaffolding happens, the model class for my entities get rebuilt. I know I know, why don’t you just use CodeFirst, well… I prefer this, not a big fan of creating everything manually.

So a perfectly working example in MVC:

  public class CustomerMetadata
    {
        [Required]
        [Display(Name =nameof(Resources.Resource.Name), ResourceType =typeof(Resources.Resource))]
        public string FirstName { get; set; }

        [Required]
        [Display(Name = nameof(Resources.Resource.Id), ResourceType = typeof(Resources.Resource))]
        public string Identifier { get; set; }
        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }

        [Display(Name = nameof(Resources.Resource.Phone), ResourceType = typeof(Resources.Resource))]
        public string Phone { get; set; }

        [Display(Name = nameof(Resources.Resource.Phone2), ResourceType = typeof(Resources.Resource))]
        public string Phone2 { get; set; }

        [Display(Name = nameof(Resources.Resource.Address), ResourceType = typeof(Resources.Resource))]
        public string Address { get; set; }

        [Display(Name = nameof(Resources.Resource.City), ResourceType = typeof(Resources.Resource))]
        public string City { get; set; }

        [Display(Name = nameof(Resources.Resource.Country), ResourceType = typeof(Resources.Resource))]
        public string Country { get; set; }

    }

    [ModelMetadataType(typeof(CustomerMetadata))]
    public partial class Customer { }

This doesn’t work in Blazor, at least for me, although the solution was kinda easy, what I ended doing was to make the class CustomerMetadata inherit from Customer, and use that class as the Model in the EditForm in Blazor, and voalá, everything work.

  public class CustomerModelValidator: Customer
    {
        [Required]
        [Display(Name = nameof(Resources.Resource.Name), ResourceType = typeof(Resources.Resource))]
        public new string FirstName { get; set; }

        [Required]
        [Display(Name = nameof(Resources.Resource.Id), ResourceType = typeof(Resources.Resource))]
        public new string Identifier { get; set; }
        [DataType(DataType.EmailAddress)]
        public new string Email { get; set; }

        [Display(Name = nameof(Resources.Resource.Phone), ResourceType = typeof(Resources.Resource))]
        public new string Phone { get; set; }

        [Display(Name = nameof(Resources.Resource.Phone2), ResourceType = typeof(Resources.Resource))]
        public new string Phone2 { get; set; }

        [Display(Name = nameof(Resources.Resource.Address), ResourceType = typeof(Resources.Resource))]
        public new string Address { get; set; }

        [Display(Name = nameof(Resources.Resource.City), ResourceType = typeof(Resources.Resource))]
        public new string City { get; set; }

        [Display(Name = nameof(Resources.Resource.Country), ResourceType = typeof(Resources.Resource))]
        public new string Country { get; set; }

    }

Please note that I use the new keyword to avoid the notification of hidden properties.