DEV Community

Cover image for ASP .NET Core IDisplayMetadataProvider
Karen Payne
Karen Payne

Posted on

ASP .NET Core IDisplayMetadataProvider

Introduction

Learn how to use a class that implements IDisplayMetadataProvider to transform property names such as FirstName to First Name.

Example for an HTML table

Example for an HTML table

Example for a standard edit page
Example for a standard edit page

Using the provided class is not a replacement for using the Display attribute; instead, it is an option to consider.

Example class using the Display attribute

public partial class Person
{
    public int PersonId { get; set; }
    [Display(Name = "First Name")]
    public string FirstName { get; set; }
    [Display(Name = "Last Name")]
    public string LastName { get; set; }
    [Display(Name = "Email Address")]
    public string EmailAddress { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Example class using the the custom provider

public partial class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAddress { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Using PascalCaseDisplayMetadataProvider

PascalCaseDisplayMetadataProvider setup.

builder.Services.AddControllersWithViews(options =>
{
    options.ModelMetadataDetailsProviders.Add(
        new PascalCaseDisplayMetadataProvider([typeof(Person)], 
            includeDerivedTypes: false));
});
Enter fullscreen mode Exit fullscreen mode
  • Parameter 1: A collection of objects representing the target types for which the display metadata should be customized.
  • Parameter 2: A boolean value indicating whether derived types of the specified in parameter 1.

Alternate setup which dynamically gets all classes under a specific folder.

In this case all classes are in a folder named Models. Add the following method to Program.cs

static string[] GetClassNamesFromAssembly(Assembly assembly, string? @namespace = null) =>
    assembly
        .GetTypes()
        .Where(t => t is { IsClass: true, IsAbstract: false })
        .Where(t => @namespace == null || t.Namespace == @namespace)
        .Select(t => t.Name)
        .Distinct()
        .OrderBy(n => n)
        .ToArray();
Enter fullscreen mode Exit fullscreen mode

Setup in Main method

string ns = typeof(Program).Namespace!;

string[] classNames = GetClassNamesFromAssembly(typeof(Program).Assembly, $"{ns}.Models");

// Configures a custom display metadata provider to format PascalCase property names into a more readable format.
builder.Services.AddControllersWithViews(options =>
{
    options.ModelMetadataDetailsProviders.Add(
        new PascalCaseDisplayMetadataProvider(
            [.. classNames
                .Select(name => Type.GetType($"{ns}.Models.{name}"))
                .Where(type => type is not null)
                .Cast<Type>()],
            includeDerivedTypes: false));
});
Enter fullscreen mode Exit fullscreen mode

💡 A developer, rather than copy PascalCaseDisplayMetadataProvider to their project, use the provided class project AspCoreHelperLibrary and create a project reference.

⌨️ Source code

The sample project provided was selected at random, which, in addition to demonstrating code that showcases PascalCaseDisplayMetadataProvider, also illustrates how to utilize FluentValidation and specify required properties via CSS.

Source code

More to follow

Will be creating more articles on this topic soon.

Top comments (0)