asp.net mvc自定義特性+過濾器 實現請求時呼叫自定義方法
阿新 • • 發佈:2019-01-23
一:定義一個特性
[AttributeUsage(AttributeTargets.Method)] //用於方法的特性
public class UniteAttribute : System.Attribute
{
public string method { get; set; }
public string target { get; set; }
public UniteAttribute()
{
}
}
二:在需要的方法上配置好該特性
[UniteAttribute(target="Myprice",method="Test")] public ActionResult Login(string LoginName, string Password) { return View(); }
三:建立好類Myprice與方法Test
public class Myprice
{
public Myprice()
{
}
public void Test(HttpRequestBase _request)
{
string aa = _request["aa"];
string bb = _request["bb"];
}
}
四:使用過濾器獲取方法特性,然後用反射呼叫方法即可
public override void OnActionExecuting(ActionExecutingContext filterContext) { //得到Controller型別 Type t = filterContext.ActionDescriptor.ControllerDescriptor.ControllerType; //得到方法名 string actionname = filterContext.RouteData.Values["action"].ToString(); //獲取自定義的特性 object[] astri = GetThatAttribute<UniteAttribute>(actionname, t); if (astri.Length > 0) { //更具自定義的特性得到需要呼叫的類名與方法名 UniteAttribute u = astri[0] as UniteAttribute; //從配置檔案得到名稱空間 string sapcename = System.Configuration.ConfigurationManager.AppSettings["UniteNameSapce"].ToString(); string fullname =""; //如果只用類全名就不能呼叫其他庫的方法了,只能呼叫當前的庫下 object libraryName = System.Configuration.ConfigurationManager.AppSettings["UniteLibrary"]; if (libraryName == null) fullname = sapcename + "." + u.target; else fullname = sapcename + "." + u.target + "," + libraryName.ToString(); string methodname = u.method; //反射呼叫方法,引數為request Type tm = Type.GetType(fullname); object obj = Activator.CreateInstance(tm); Activator.CreateInstance(tm).GetType().GetMethod(methodname).Invoke(obj, new Object[] { filterContext.HttpContext.Request }); } base.OnActionExecuting(filterContext); } public object[] GetThatAttribute<T>(string methodname, Type t) { return t.GetMethod(methodname).GetCustomAttributes(typeof(T), true); } public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); } }
如果方法需要在action方法執行完後再執行可以在OnActionExecuted方法裡邊去呼叫配置的方法
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (bi.isbehind)
InvokeWay(bi.filterContext, bi.u);
base.OnActionExecuted(filterContext);
}
過濾器使用全部過濾器
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new IsLoginFilter());
filters.Add(new UniteFilter());
}
}
也可以在想要的action配置該過濾器
配置好類所有的名稱空間與程式集名稱,如果程式集名稱在本地可以不用配置
<add key="UniteNameSapce" value="YuanJia.LianMeng"/>
<add key="UniteLibrary" value="YuanJia"/>
注意過濾器使用的是同一個物件,如果在過濾器使用了全域性變數,併發時就會有問題,所以如果需要設定一個引數,可以利用HttpContext.Items,因為每個請求的HttpContext.Items都是不同的物件
filterContext.HttpContext.Items.Add("time", DateTime.Now.ToString());
filterContext.HttpContext.Items.Add("target", u.target);
filterContext.HttpContext.Items.Add("method", u.method);