抱歉讓大家久等了,最近有點忙,所以一直沒時間更新博客。
上篇文章中我們已經解決ajax請求調用業務類方法帶參數的問題,但很多業務類的方法我們肯定是不希望暴露給ajax請求的,這篇文章我們就來解決請求方法授權的問題。
上篇中我們已經用到了特性Attribute給方法參數定義取值,那授權我們是不是也可以通過Attribute來實現呢,當然是可以的。WebService相信大家都用過,WebService的方法都帶了一個WebMethod,我們也定義一個類似的特性類AjaxMethod:
[AttributeUsage(AttributeTargets.Method)] public class AjaxMethod:Attribute { public static bool IsAjaxMethod(System.Reflection.MethodInfo method) { return Attribute.IsDefined(method, typeof(AjaxMethod)); } }
僅僅是定義一個類而已,附帶了一個靜態方法,其它的什么都不用做,因為它僅用來給我們的業務方法作標識。
那判定某個方法是不是可以響應就很簡單了,我們在之前的代碼中已經通過反射取得了要調用的方法信息,這時只要調用AjaxMethodAttribute的方法就可以知道是否允許Ajax調用,不允許則直接返回,不執行反射取得的方法。
相信不少業務類中的方法都是需要用戶登錄后才能使用的,如果不解決這個問題,我們每個方法都需要去驗證用戶是否已經登錄,比較麻煩,既然已經講到了授權,我們就順帶把這個問題解決了。
還是使用特性,我們定義一個AuthorizationAttribute特性類:
[AttributeUsage(AttributeTargets.Method)] public abstract class AuthorizationAttribute : Attribute { public abstract bool Validate(System.Web.HttpContext context); }
為了方便擴展,我們把這個類定義成一個抽象類,並加上一個抽象方法來驗證授權,那我們就可以隨意給方法定義授權了,如:IsUserAttribute,IsAdministratorAttribute。我們隨便定義一個IsUserAttribute類看看:
public class IsUserAttribute : AuthorizationAttribute { public override bool Validate(System.Web.HttpContext context) { var cookie = context.Request.Cookies["user"]; return cookie != null && cookie.Value == "1"; } }
接下來我們原來的Factory.Execute方法需要作出些修改以驗證授權:
void Execute(HttpContext context) { //根據請求的Url,通過反射取得處理該請求的類 string url = context.Request.Url.AbsolutePath; string[] array = url.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); string typename = "Biz"; for (int x = 1; x < array.Length - 1; x++) { typename += "." + array[x]; } Type type = this.GetType().Assembly.GetType(typename, false, true); if (type != null) { //取得類的無參數構造函數 var constructor = type.GetConstructor(new Type[0]); //調用構造函數取得類的實例 var obj = constructor.Invoke(null); //查找請求的方法 var method = type.GetMethod(System.IO.Path.GetFileNameWithoutExtension(url)); if (method != null && AjaxMethod.IsAjaxMethod(method)) { var attrList = Attribute.GetCustomAttributes(method, typeof(AuthorizationAttribute)); if (attrList != null && attrList.Length > 0) { bool flag = false; foreach (AuthorizationAttribute item in attrList) { if (item.Validate(context)) { flag = true; break; } } if (!flag) { return; } } var parameters = method.GetParameters(); object[] args = null; if (parameters.Length > 0) { args = new object[parameters.Length]; for (int x = 0; x < parameters.Length; x++) { var parameterAttr = (Attribute.GetCustomAttribute(parameters[x], typeof(ParameterAttribute)) as ParameterAttribute) ?? new FormAttribute(); parameterAttr.Name = parameterAttr.Name ?? parameters[x].Name; args[x] = parameterAttr.GetValue(context, parameters[x].ParameterType); } } //執行方法並輸出響應結果 method.Invoke(obj, args); //context.Response.Write(method.Invoke(obj, args)); } } }
至此,我們對方法訪問授權的問題已經解決,未標識AjaxMethod的方法將不能通過Ajax調用,標識了AuthorizationAttribute特性的類需要通過指定的授權才能訪問,后期也可以根據需要繼承AuthorizationAttribute實現特定的授權需求。
時間倉促,寫得比較亂,大家湊合着看看吧,歡迎回復交流分享經驗!
性能優化部分如果有時間,我會盡力分享,感謝大家的關注。