Created
October 30, 2025 00:09
-
-
Save karenpayneoregon/8109e2de33183d8d176ce26a511c2f2b to your computer and use it in GitHub Desktop.
Pascal Case Display Names
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; | |
| using System.Text.RegularExpressions; | |
| namespace TODO.Classes; | |
| /// <summary> | |
| /// Provides a custom implementation of <see cref="IDisplayMetadataProvider"/> | |
| /// to format property names in PascalCase into a more readable format by inserting spaces. | |
| /// </summary> | |
| /// <remarks> | |
| /// This class is designed to enhance the display metadata for properties in an ASP.NET Core MVC application. | |
| /// It modifies the display name of properties by splitting PascalCase names into separate words, | |
| /// unless a display name is already explicitly provided. | |
| /// </remarks> | |
| public sealed partial class PascalCaseDisplayMetadataProvider : IDisplayMetadataProvider | |
| { | |
| public void CreateDisplayMetadata(DisplayMetadataProviderContext context) | |
| { | |
| if (context == null) throw new ArgumentNullException(nameof(context)); | |
| // Only touch property names, and only when no Display/DisplayName is already supplied. | |
| if (context.Key.MetadataKind != ModelMetadataKind.Property) | |
| return; | |
| var existing = context.DisplayMetadata.DisplayName?.Invoke(); | |
| if (!string.IsNullOrEmpty(existing)) | |
| return; | |
| context.DisplayMetadata.DisplayName = () => SplitPascalCase(context.Key.Name ?? string.Empty); | |
| } | |
| private static string SplitPascalCase(string sender) | |
| { | |
| if (string.IsNullOrWhiteSpace(sender)) return sender; | |
| // Insert a space before capital letters that either: | |
| // - follow a lowercase/number, or | |
| // - start an Upper-lower sequence (handles “UnitPrice”, “IDNumber”, etc.) | |
| return SplitPascalCaseRegex().Replace(sender, " $1"); | |
| } | |
| [GeneratedRegex("(?<=.)([A-Z](?=[a-z])|(?<=[a-z0-9])[A-Z])")] | |
| private static partial Regex SplitPascalCaseRegex(); | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Program | |
| { | |
| public static void Main(string[] args) | |
| { | |
| var builder = WebApplication.CreateBuilder(args); | |
| builder.Services.AddRazorPages(); | |
| builder.Services | |
| .AddRazorPages() | |
| .AddMvcOptions(options => | |
| { | |
| // Add provider alongside the defaults | |
| options.ModelMetadataDetailsProviders.Add(new PascalCaseDisplayMetadataProvider()); | |
| }); | |
| builder.Services.AddValidatorsFromAssemblyContaining<ContactValidator>(); | |
| ... | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment