Reputation: 403
I am looking for an efficient way to automatically format data fields in an entity - ideally using attributes.
We need to generate a PDF file from the data model. We want to ensure consistency in the deliverable, so we're looking 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'd rather not re-invent the wheel. I see a lot of promise using DataAnnotations (especially the DisplayFormat attribute), but I can't seem to find any built-in classes that work with those attributes.
How do I do this in a non-UI (i.e. non-MVC) context?
Here's an example of what we're 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, i.e. (888)555-1234 based on its decorations.
}
}
I am also open to solutions that create a "view" of the data rather than update the original object, that is:
MyDataModel formatted = original.FormatData();
Whatever requires the least amount of code is ideal.
Upvotes: 4
Views: 2445
Reputation: 12255
You can use a 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 thing for zip codes, or whatever is a predictable format like that.
Maybe not super clean but it sure is quick and easy.
Edit: I added a regex to make sure only numbers are used as an input in case a a user used hyphens or parentheses on input.
Upvotes: 0
Reputation: 43087
You'll have to use reflection to read a type's property's attributes. This answer provides a few extension methods that should help. It's for an MVC question, but it will work outside of MVC as well:
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;
}
Usage would be:
string displayName = ReflectionExtensions.GetPropertyDisplayName<SomeClass>(i => i.SomeProperty);
Upvotes: 2