How to add Display attribute to model

.net-core c# entity-framework-core

Question

Example.

public class Product
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string ProductName { get; set; }

    public int OrderId { get; set; }
    public Order Order { get; set; }
}

public class Order
{
    [Key]
    public int Id { get; set; }

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

    public IEnumerable<Product> Products { get; set; }
}

Models are in a separate project, because I want to use them in several applications that work with the same database. The 'Display' attribute name can be different in different applications. I can not inherit classes in applications and set attributes in metadata because can not cast IEnumerable<Product> to IEnumerable<DerivedProduct>. What do I do?

1
0
1/24/2018 10:25:06 AM

Accepted Answer

Well. It's not possible add attributes from other class automatically. You need write your own metadata provider inherited from IDisplayMetadataProvider (if you want edit property display settings) or/and IValidationMetadataProvider (if you want edit property validation messages).

   public class MyMetadataProvider : IDisplayMetadataProvider, IValidationMetadataProvider
    {
        public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
        {
        }

        public void CreateValidationMetadata(ValidationMetadataProviderContext context)
        {
        }
    }

In ASP .NET Core MVC you need add instance of your provider to provider list in Startup.cs.

services.AddMvc(c=>c.ModelMetadataDetailsProviders.Add(new MyMetadataProvider()));
0
1/29/2018 10:03:13 AM

Popular Answer

There is possibility to define validation attributes in separate class, that is then linked with original class through MetadataType attribute.

Here is how to do it for Product class:

1.Declare ProductMetadata class with the same properties that original class has:

internal class ProductMetadata
{
    [Key]
    public int Id { get; set; }

    [Required]
    [Display(Name = "SomeName")]
    public string ProductName { get; set; }

    public int OrderId { get; set; }

    public Order Order { get; set; }
}

2.If possible, remove any attributes from System.ComponentModel.DataAnnotations namespace from your your original class Product. This step is optional and is desirable for avoiding unused attributes. If you can't modify original class or those attributes are required for some reasons, leave them as is.

3.Now you have to mark original class with MetadataType attribute specifying metadata class type. If you could add the attribute to existing class Product then it's simple:

[MetadataType(typeof(ProductMetadata))]
public class Product
{
    // ...
}

If however the model class is in separate project as you describe, you could assign that attribute dynamically. Put this code somewhere close to application startup:

TypeDescriptor.AddAttributes(typeof(Product), new MetadataTypeAttribute(typeof(ProductMetadata)));

That's it. These steps should do the trick.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow