Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically generating data annotations from camel case field names

I am working on a project with a huge number of data tables and displaying them through ASP.net MVC screens.

I find myself writing a lot of simple data annotations like this:

 [Display(Name = "Manager Name")]
 public string ManagerName { get; set; }

 [Display(Name = "Employee Name")]
 public string EmployeeName { get; set; }

 [Display(Name = "Employee No")]
 public string EmployeeNo { get; set; }

 [Display(Name = "Manager Employee No")]
 public string ManagerEmployeeNo { get; set; }

This is getting quite tedious and was wondering if there is a way that I can either add a new attribute that says "convertFromCamel" (or something) or is there a way to override

 @Html.DisplayNameFor(m => Model.First().EmployeeNo)

So that if there is no data annotation it converts the existing field name from camel case.

thanks in advance

like image 547
Lobsterpants Avatar asked May 21 '15 08:05

Lobsterpants


People also ask

Which data annotation attribute can be used to define a primary key property?

You can use the key annotation to specify which property is to be used as the EntityKey. If you are using code first's database generation feature, the Blog table will have a primary key column named PrimaryTrackingKey, which is also defined as Identity by default.

What is data annotation in Entity Framework?

DataAnnotations is used to configure the classes which will highlight the most commonly needed configurations. DataAnnotations are also understood by a number of . NET applications, such as ASP.NET MVC which allows these applications to leverage the same annotations for client-side validations.


1 Answers

Using a combination of the information found on the blog here, and the excellent camel-case split regex here, I was able to work this out. The concept is that you create a custom flavour of the default DataAnnotationsModelMetadataProvider. In the case where a property does not have a display name already, this custom provider kicks in and creates one for you (with spaces).

First, create a class:

using System;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Web.Mvc;

namespace MyProject.Whatever
{
    public class CustomDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider
    {
        protected override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, PropertyDescriptor propertyDescriptor)
        {
            ModelMetadata metadata = base.GetMetadataForProperty(modelAccessor, containerType, propertyDescriptor);
            if (metadata.DisplayName == null)
            {
                metadata.DisplayName = SplitCamelCase(metadata.GetDisplayName());
            }
            return metadata;
        }

        private string SplitCamelCase(string str)
        {
            return Regex.Replace(
                Regex.Replace(
                    str,
                    @"(\P{Ll})(\P{Ll}\p{Ll})",
                    "$1 $2"
                ),
                @"(\p{Ll})(\P{Ll})",
                "$1 $2"
            );
        }
    }
}

Now override the default DataAnnotationsModelMetadataProvider in your Global.asax.cs file by doing the following:

protected void Application_Start()
{
    //Other stuff.
    ...
    ModelMetadataProviders.Current = new CustomDataAnnotationsModelMetadataProvider();
}
like image 101
Jamie Dunstan Avatar answered Oct 12 '22 12:10

Jamie Dunstan