我的项目中有一些类,某些属性Browsable(false)
,因此用户看不到它们:
public class OrderEntity{
public int Id { get; set;}
[Browsable(false)]
public int ProductId { get; set;}
....
}
我想,如果最终用户是管理员,他可以看到ProductId
,但另一个用户看不到它。
所以我需要这样的东西:
public class OrderEntity{
public int Id { get; set;}
[CustomizedBrowsable(false)]
public int ProductId { get; set;}
....
}
public class CustomizedBrowsable: Attribute
{
if(AppContext.UserCode == "Admin") // The current user code saved in a static variable AppContext.UserCode.
//do somethings
else
//do somethings else
}
这不是您可以通过属性执行的操作,因为BrowsableAttribute
是sealed
。要通过绑定执行此操作,您需要一个自定义类型描述符 - 因此您需要在类型上实现ICustomTypeDescriptor
(直接或通过TypeDescriptionProvider
(,提供自定义PropertyDescriptor
,并更改在那里定义可浏览性的方式(IsBrowsable
,IIRC(。
这是大量的工作。
坦率地说,在几乎所有情况下,最好只手动控制绑定,并且仅在检查安全级别后添加列/输入/任何内容。
我使用类代码定义了自己的AdminBrowsable
类Browsable
:
[AttributeUsage(AttributeTargets.All)]
public sealed class AdminBrowsableAttribute : Attribute
{
/// <summary>
/// Specifies that a property or event can be modified at design time. This static field is read-only.
/// </summary>
public static readonly AdminBrowsableAttribute Yes = new AdminBrowsableAttribute(true);
/// <summary>
/// Specifies that a property or event cannot be modified at design time. This static field is read-only.
/// </summary>
public static readonly AdminBrowsableAttribute No = new AdminBrowsableAttribute(false);
/// <summary>
/// Specifies the default value for the <see cref="T:System.ComponentModel.BrowsableAttribute"/>, which is <see cref="F:System.ComponentModel.BrowsableAttribute.Yes"/>. This static field is read-only.
/// </summary>
public static readonly AdminBrowsableAttribute Default = AdminBrowsableAttribute.Yes;
private bool browsable = true;
/// <summary>
/// Gets a value indicating whether an object is browsable.
/// </summary>
///
/// <returns>
/// true if the object is browsable; otherwise, false.
/// </returns>
public bool Browsable
{
get
{
return this.browsable;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="T:System.ComponentModel.BrowsableAttribute"/> class.
/// </summary>
/// <param name="browsable">true if a property or event can be modified at design time; otherwise, false. The default is true. </param>
public AdminBrowsableAttribute(bool browsable)
{
if (!AppContext.IsAdmin)
{
this.browsable = browsable;
}
}
/// <summary>
/// Indicates whether this instance and a specified object are equal.
/// </summary>
///
/// <returns>
/// true if <paramref name="obj"/> is equal to this instance; otherwise, false.
/// </returns>
/// <param name="obj">Another object to compare to. </param>
public override bool Equals(object obj)
{
if (obj == this)
return true;
AdminBrowsableAttribute browsableAttribute = obj as AdminBrowsableAttribute;
if (browsableAttribute != null)
return browsableAttribute.Browsable == this.browsable;
return false;
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
///
/// <returns>
/// A 32-bit signed integer hash code.
/// </returns>
public override int GetHashCode()
{
return this.browsable.GetHashCode();
}
/// <summary>
/// Determines if this attribute is the default.
/// </summary>
///
/// <returns>
/// true if the attribute is the default value for this attribute class; otherwise, false.
/// </returns>
public override bool IsDefaultAttribute()
{
return this.Equals((object)AdminBrowsableAttribute.Default);
}
}
我只更改了Constructor
:
public AdminBrowsableAttribute(bool browsable)
{
if (AppContext.UserCode != "Admin")
{
this.browsable = browsable;
}
}