一:定义一个特性
[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);