asp.net mvc(六)
Action和Filter
Filter在Asp.net MVC中它只能限制于Action,Controller。 继承于ActionFilterAttribute,且可以覆写如下几个重要方法。
1:void OnActionExecuting(ActionExecutingContext):Action执行前的操作
2:void OnActionExecuted(ActionExecutedContext):Action执行后的操作
3:void OnResultExecuting(ResultExecutingContext):解析ActionResult前执行
4:void OnResultExecuted(ResultExecutedContext):解析ActionResult后执行
系统提供的比较常见的Filter:
1:AcceptVerbs
2:ActionName,上面两个都限制了对Action的访问条件;
3:OutputCache,设置缓存;
4:ValidateInput,增加数据验证。
示例:
1:留言簿列表数据:可以这样写,也可以省略[AcceptVerbs(HttpVerbs.Get )],它是个默认值。这种访问是以链接形式访问。
public ActionResult Index()
{
var models = inter.FindAllInfo();
return View("Index", models);
}
2: 当创建一则留言时:我们要用HttpVerbs.Post方式。此时的Action需要在提交表单后才会执行对应的Action。
public ActionResult Create(GuestBookInfo model)
{
try
{
inter.Add(model);
var models = inter.FindAllInfo();
TempData["TempData"] = "已经成功创建";
return RedirectToAction("Index");
}
catch(Exception ex)
{
ModelState.AddModelError("ex",ex);
return View(model);
}
}
3:ActionNameAttribute的用法,和 AcceptVerbsAttribute 方式差不多,如果不指定ActionName,则系统会默认找名称和方法名相同之处的View。
public ActionResult Edit(int id)
自定义Filter:
这里创建一个没有客户端缓存的NoClientCacheAttribute。需要继承ActionFilterAttribute,且重写OnActionExecuting方法。
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext.Current.Response.CacheControl = "No-Cache";
}
}
应用在Action上,特别简单,像C#中的变通特性用法一样。
public ActionResult Details(int id)
AcceptVerbs的工作机制。
第一:AcceptVerbsAttribute类。它继承了ActionMethodSelectorAttribute,重要的方法是重写了基类的IsValidForRequest方法,这也是起过滤作用的地方。
public sealed class AcceptVerbsAttribute : ActionMethodSelectorAttribute
{
// Fields
[CompilerGenerated]
private ICollection<string> <Verbs>k__BackingField;
// Methods
public AcceptVerbsAttribute(HttpVerbs verbs);
public AcceptVerbsAttribute(params string[] verbs);
private static void AddEntryToList(HttpVerbs verbs, HttpVerbs match, List<string> verbList, string
entryText);
internal static string[] EnumToArray(HttpVerbs verbs);
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo);
// Properties
public ICollection<string> Verbs { [CompilerGenerated] get; private [CompilerGenerated] set; }
}
第二:IsValidForRequest方法:
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
string httpMethod = controllerContext.HttpContext.Request.HttpMethod;
return this.Verbs.Contains<string>(httpMethod, StringComparer.OrdinalIgnoreCase);
}
我们来看这个方法里有一个this.Verbs,它是一个Request.HttpMethod集合。它是如何初始化的呢?我们来看AcceptVerbsAttribute的构造函数。它会同时调用另外一个构造函数public AcceptVerbsAttribute(params string[] verbs)
{
}
重要的就是下面的EnumToArray方法和AddEntryToList方法,EnumToArray方法负责收集所有的Request.HttpMethod,AddEntryToList方法是把当前访问类型同所有Request.HttpMethod做比较,取出它们的交集。
internal static string[] EnumToArray(HttpVerbs verbs)
{
List<string> verbList = new List<string>();
AddEntryToList(verbs, HttpVerbs.Get, verbList, "GET");
AddEntryToList(verbs, HttpVerbs.Post, verbList, "POST");
AddEntryToList(verbs, HttpVerbs.Put, verbList, "PUT");
AddEntryToList(verbs, HttpVerbs.Delete, verbList, "DELETE");
AddEntryToList(verbs, HttpVerbs.Head, verbList, "HEAD");
return verbList.ToArray();
}
{
if ((verbs & match) != 0)
{
verbList.Add(entryText);
}
}
再回头看下IsValidForRequest方法,就很容易理解这个Filer为什么能够直到过滤的作用了。
总结:利用Filter的特点,我们可以写一些扩展性的内容,例如:压缩页面的Attibute,无缓存的Attibute等等。
注:本文引用:http://www.rainsts.net/article.asp?id=786