Formatting a field using attributes in C # - DisplayFormatAttribute?

I am looking for an effective way to automatically format data fields in essence - ideally using attributes.

We need to create a PDF file from the data model. We want to ensure consistency in the delivered product, so we strive to apply some formatting rules to certain data fields (dates, phone numbers, zip codes, etc.). Of course, I could write custom attributes and formatting code, but I would prefer not to reinvent the wheel. I see many promises using DataAnnotations (especially the DisplayFormat attribute), but I cannot find any built-in classes that work with these attributes.

How to do this in a context other than the UI (for example, not MVC)?

Here is an example of what we are looking for:

public class MyDataModel { [PhoneNumber] public string PhoneNumber { get; set; } public void FormatData() { //Invoke some .NET or other method changes the value of PhoneNumber into a desired format, ie (888)555-1234 based on its decorations. } } 

I am also open to solutions that create a โ€œpresentationโ€ of data, and not to update the original object, namely:

 MyDataModel formatted = original.FormatData(); 

Whatever requires the least amount of code, is ideal.

+4
source share
2 answers

You will need to use reflection to read the attributes of the type properties. This answer contains several extension methods that should help. This is an MVC question, but it will work outside of MVC too:


 public static T GetAttribute<T>(this MemberInfo member, bool isRequired) where T : Attribute { var attribute = member.GetCustomAttributes(typeof(T), false).SingleOrDefault(); if (attribute == null && isRequired) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "The {0} attribute must be defined on member {1}", typeof(T).Name, member.Name)); } return (T)attribute; } public static string GetPropertyDisplayName<T>(Expression<Func<T, object>> propertyExpression) { var memberInfo = GetPropertyInformation(propertyExpression.Body); if (memberInfo == null) { throw new ArgumentException( "No property reference expression was found.", "propertyExpression"); } var attr = memberInfo.GetAttribute<DisplayNameAttribute>(false); if (attr == null) { return memberInfo.Name; } return attr.DisplayName; } public static MemberInfo GetPropertyInformation(Expression propertyExpression) { Debug.Assert(propertyExpression != null, "propertyExpression != null"); MemberExpression memberExpr = propertyExpression as MemberExpression; if (memberExpr == null) { UnaryExpression unaryExpr = propertyExpression as UnaryExpression; if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert) { memberExpr = unaryExpr.Operand as MemberExpression; } } if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property) { return memberExpr.Member; } return null; } 

Using:

 string displayName = ReflectionExtensions.GetPropertyDisplayName<SomeClass>(i => i.SomeProperty); 
+2
source

You can use MaskedTextBox

 MaskedTextBox mtb = new MaskedTextBox(); mtb.Mask = "(999) 000-0000"; inputString=Regex.Replace(inputString, @"\D+", ""); mtb.Text = inputString; 

Then you check the text ...

string s = mtb.Text; //s = "(204) 867-5309"

You can do the same for zip codes or something like a predictable format.

It may not be super clean, but it sure is quick and easy.

Edit: I added a regular expression to make sure that only numbers are used as input if the user used hyphens or parentheses in the input.

0
source

Source: https://habr.com/ru/post/1396247/


All Articles