Action Filter 与 内置的Filter实现(实例-防盗链)




首先继承自FilterAttribute类同时实现IActionFilter接口,代码如下:
  1. /**//// <summary>
  2. /// 防盗链Filter.
  3. /// </summary>
  4. public class AntiOutSiteLinkAttribute : ActionFilterAttribute, IActionFilter
  5. {
  6.     public AntiOutSiteLinkAttribute(FileType fileType)
  7.     {
  8.         this.FileType = fileType;
  9.     }
  10.     /**//// <summary>
  11.     /// 请求的文件类型.(文件或图片)
  12.     /// </summary>
  13.     public FileType FileType { get; set; }
  14.     IActionFilter 成员#region IActionFilter 成员
  15.     void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
  16.     {
  17.         HttpContextBase httpContext = filterContext.HttpContext;
  18.         if (null != httpContext.Request.UrlReferrer)
  19.         {
  20.             string serverDomain = httpContext.Request.Url.Host;
  21.             string refDomain = httpContext.Request.UrlReferrer.Host;
  22.             if (GetRootDomain(refDomain).Equals(GetRootDomain(serverDomain), StringComparison.OrdinalIgnoreCase))
  23.             {
  24.                 return;//如果根域名相同就返回
  25.             }
  26.         }
  27.         ContentResult cr = new ContentResult();
  28.         if (FileType == FileType.Image)
  29.         {
  30.             cr.ContentType = "image/jpeg";
  31.             FileInfo fi = new FileInfo(httpContext.Server.MapPath("~/Content/images/outsitelink.jpg"));
  32.             if (fi.Exists)
  33.             {
  34.                 httpContext.Response.WriteFile(fi.FullName);
  35.             }
  36.             else
  37.             {
  38.                 Bitmap bmp = new Bitmap(200, 50);
  39.                 Graphics g = Graphics.FromImage(bmp);
  40.                 g.FillRectangle(Brushes.White, 0, 0, 200, 50);
  41.                 g.DrawString("请不要盗链", new Font("Arial", 15), Brushes.Red, new PointF(0, 0));
  42.                 bmp.Save(httpContext.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
  43.             }
  44.         }
  45.         else
  46.         {
  47.             cr.ContentType = "text/html";
  48.             cr.Content = string.Format("请不要盗链。返回<a href='{0}'>{1}</a>", Utils.AbsoluteWebRoot, BlogSettings.Instance.Name);
  49.         }
  50.         //将当前的上下文的ActionResult设置为我们的cr(ContentResult)
  51.         filterContext.Result = cr;
  52.     }
  53.     #endregion
  54.     /**//// <summary>
  55.     /// 获取网站的根域名
  56.     /// </summary>
  57.     /// <param name="domain">网站的域名,不带"Http://"</param>
  58.     /// <returns></returns>
  59.     private string GetRootDomain(string domain)
  60.     {
  61.         if (string.IsNullOrEmpty(domain))
  62.         {
  63.             throw new ArgumentNullException("参数'domain'不能为空");
  64.         }
  65.         string[] arr = domain.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
  66.         if (arr.Length <= 2)
  67.         {
  68.             return domain;
  69.         }
  70.         else
  71.         {
  72.             return arr[arr.Length - 2] + "." + arr[arr.Length - 1];
  73.         }
  74.     }
  75. }
  76. public enum FileType
  77. {
  78.     File = 1,
  79.     Image
  80. }
复制代码
然后我们建立一个用于处理文件请求的Controller,并应用上我们刚才建立的Filter:
  1. public class FilesController : BaseController
  2. {
  3.     [AntiOutSiteLink(FileType.Image)]
  4.     public ActionResult Image(string file)
  5.     {
  6.         return Content("Image From 4mvc");
  7.     } 
  8.     [AntiOutSiteLink(FileType.File)]
  9.     public ActionResult File(string file)
  10.     {
  11.         return Content("File From 4mvc");
  12.     }
  13. }
复制代码
posted @ 2012-02-09 10:57  左轮death029  阅读(276)  评论(0编辑  收藏  举报