前言
最近做許可權控制,對頁面的許可權控制使用IHttpModule做的,想把控制粒度細化到頁面上控制項的許可權判斷,意圖是傳入控制項編號,根據控制項編號和目前使用者的許可權,如果沒有許可權的話就把控制項隱藏或顯示為不可用,打算用Attribute來做,以下是遇到的一些問題和看法,雖然失敗了但是覺得仍然有參考價值。
推薦幾篇文章:
1. Attribute在.net編程中的應用(一)
2. Attribute在.net編程中的應用(二)
3. Attribute在.NET編程中的應用(三)
4. " href="http://dudu.cnblogs.com/articles/4452.html">Attribute在.NET編程中的應用(四)
5. CLR筆記:17.自訂屬性
本文:
先看我的錯誤碼:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Method)]
public class PowerAttribute : Attribute
{
/// <summary>
/// 對頁面內控制項進行許可權判斷,許可權的字串組成:URL+"?id"+Control.ID
/// 例如:/page/index?id=tbName
/// </summary>
/// <param name="pType"></param>
/// <param name="control"></param>
public PowerAttribute(PowerType pType, params WebControl[] control)
{
for (int i = control.Length; --i >= 0; )
{
WebControl Control = control.GetValue(i) as WebControl;
if (Control != null)
if (HasPower(string.Concat(WebHelper.WebRequest.Path, "?id=", Control.ID)) == -1)//判斷許可權
if (pType == PowerType.Visible)
Control.Visible = false;
else
Control.Enabled = false;
}
}
public int HasPower(string path)
{
return -1;
}
/// <summary>
/// 獲得控制項的許可權,1 具有許可權,0 使用者逾時,-1 沒有許可權
/// </summary>
/// <param name="control"></param>
/// <param name="Field"></param>
public PowerAttribute(WebControl control, ref int Field)
{
Field = HasPower(string.Concat(WebHelper.WebRequest.Path, "?id=", control.ID));
}
/// <summary>
/// 獲得頁面的許可權,1 具有許可權,0 使用者逾時,-1 沒有許可權
/// </summary>
/// <param name="control"></param>
/// <param name="Field"></param>
public PowerAttribute(ref int Field)
{
Field = HasPower(WebHelper.WebRequest.Path);
}
}
意圖比較明顯,想在要控制控制項許可權的頁面裡面加一個Attribute標記傳入控制項編號就能自動把其設定為指定的顯示狀態,可是失敗了!以下是錯誤資訊:
屬性參數必須是常量運算式、typeof 運算式或數組建立運算式 ConsoleTest
也就是說沒法傳,也不能夠用ref來傳遞引用!也就是說沒有辦法直接改變頁面上的控制項或欄位的值,這讓我忽然想起了DefaultValueAttribute,MSDN的解釋是
指定屬性 (Property) 的預設值。我發現有許多朋友有點誤會這個,先看代碼:
static void Main(string[] args)
{
AttributeCollection attributes = TypeDescriptor.GetProperties(new MyClass())["MyProperty"].Attributes;
/* Prints the default value by retrieving the DefaultValueAttribute
* from the AttributeCollection. */
DefaultValueAttribute myAttribute =
(DefaultValueAttribute)attributes[typeof(DefaultValueAttribute)];
Console.WriteLine("The default value is: " + myAttribute.Value.ToString());
Console.Read();
}
class MyClass
{
private bool myVal = false;
[DefaultValue(false)]
public bool MyProperty
{
get
{
return myVal;
}
set
{
myVal = value;
}
}
}
這是MSDN例子,注意看兩點:
1. DefaultValue傳入參數為false,而myVal設定的也是false
2. 再看調用的地方,是使用的DefaultValueAttribute,而不是直接存取的屬性MyProperty
狐疑了吧,他設定的預設值不是屬性MyProperty的預設值!!不信的話你可以把[DefaultValue(false)]改成[DefaultValue(true)],然後直接Console.WriteLine(new MyClass().MyProperty);!!
從上面參考的幾篇文章中可以發現,Attribute可以做方法參數校正、也可以為過時的方法做標記 ObsoleteAttribute、為方法傳參,雖然如此,但是仍然覺的使用起來並不方便,只是看起來比較酷罷了,一個類居然可以這樣使用!!可以把這個類僅僅使用在類、方法、欄位上,也可以使用所以地方,控制使用次數,顯然仍然是有他的用處的,沒法把你的代碼和他耦合起來,也是用反射來實現相關功能的!!
說到這裡實在還是不太明白,但是起碼知道DefaultValueAttribute不是為當前類設定預設值的,所以使用的時候注意Attribute概念問題!歡迎大家提意見: )