我在ASP.net MVC4网站上工作;视图模型层由于某些原因我对Model和ViewModel 中的一些属性有不同的名称
型号
public partial class Project
{
public string Desc {get; set;}
}
查看模型
public class ProjectViewModel
{
public string Description { get; set; }
}
现在在模型层,如果属性不同,我需要使用ViewModel名称。我想创建一个自定义属性,这样我就可以在模型中拥有这样的东西:
public partial class Project
{
[ViewModelPropertyName("Description")]
public string Desc {get;set;}
}
并在模型层将其用作
string.Format("ViewModel Property Name is {0}", this.Desc.ViewModelPropertyName())
我希望这是通用的,这样,如果一个属性上没有ViewModelPropertyName
属性,那么它应该返回相同的属性名称,即如果Desc
属性没有属性,那么应该只返回"Desc"
。
这是我尝试过的
public class ViewModelPropertyNameAttribute : System.Attribute
{
#region Fields
string viewModelPropertyName;
#endregion
#region Properties
public string GetViewModelPropertyName()
{
return viewModelPropertyName;
}
#endregion
#region Constructor
public ViewModelPropertyNameAttribute(string propertyName)
{
this.viewModelPropertyName = propertyName;
}
#endregion
}
需要如何访问自定义属性的帮助
当前状态
public static class ModelExtensionMethods
{
public static string ViewModelPropertyName(this Object obj)
{
// ERROR: Cannot convert from 'object' to 'System.Reflect.Assembly'
System.Attribute[] attrs = System.Attribute.GetCustomAttributes(obj);
foreach (System.Attribute attr in attrs)
{
if (attr is ViewModelPropertyNameAttribute)
{
return ((ViewModelPropertyNameAttribute)attr).GetViewModelPropertyName();
}
}
return string.Empty;
}
}
但这有编译时错误:
不幸的是,您无法通过反映属性本身的类型来获得用于装饰属性的属性。因此,我稍微修改了ViewModelPropertyName(此对象)Extension方法,以采用所需属性的名称。
此方法现在将接受您希望获取其属性的属性的名称。如果属性存在,它将返回传递给其构造函数的值,另一方面,如果它不存在,它只会返回您传递的属性的名称。
public static class ModelExtensionMethods
{
public static string ViewModelPropertyName(this object obj, string name)
{
var attributes = obj.GetType()
.GetCustomAttributes(true)
.OfType<MetadataTypeAttribute>()
.First()
.MetadataClassType
.GetProperty(name)
.GetCustomAttributes(true);
if (attributes.OfType<ViewModelPropertyNameAttribute>().Any())
{
return attributes.OfType<ViewModelPropertyNameAttribute>()
.First()
.GetViewModelPropertyName();
}
else
{
return name;
}
}
}
您还可以定义以下类来测试这种新方法。
[MetadataType(typeof(TestClassMeta))]
class TestClass { }
class TestClassMeta
{
[ViewModelPropertyName("TheName")]
public string FirstName { get; set; }
public string LastName { get; set; }
}
此外,从下面的代码行中可以看到,您的ViewModelPropertyName(此对象,字符串)Extension方法现在将在TestClass的实例上调用,而不是在属性本身上调用它。
class Program
{
static void Main()
{
Console.WriteLine(new TestClass().ViewModelPropertyName("FirstName"));
Console.WriteLine(new TestClass().ViewModelPropertyName("LastName"));
Console.Read();
}
}