我正在寻找一种有效的方法来自动格式化实体中的数据字段 – 理想情况下使用属性.
我们需要从数据模型生成PDF文件.我们希望确保可交付成果的一致性,因此我们希望将某些格式规则应用于某些数据字段(日期,电话号码,邮政编码等).当然,我可以编写自定义属性和格式化代码,但我宁愿不重新发明轮子.我看到很多使用DataAnnotations的承诺(特别是DisplayFormat属性),但我似乎找不到任何与这些属性一起使用的内置类.
如何在非UI(即非MVC)上下文中执行此操作?
这是我们正在寻找的一个例子:
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.
}
}
我也对创建数据“视图”的解决方案持开放态度,而不是更新原始对象,即:
MyDataModel formatted = original.FormatData();
无论什么需要最少的代码是理想的.
最佳答案 您必须使用反射来读取类型属性的属性.
This answer提供了一些应该有用的扩展方法.这是一个MVC问题,但它也可以在MVC之外工作:
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;
}
用法是:
string displayName = ReflectionExtensions.GetPropertyDisplayName<SomeClass>(i => i.SomeProperty);