首先继承自FilterAttribute类同时实现IActionFilter接口,代码如下:
//// <summary> /// 防盗链Filter. /// </summary> public class AntiOutSiteLinkAttribute : ActionFilterAttribute, IActionFilter { public AntiOutSiteLinkAttribute(FileType fileType) { this.FileType = fileType; } //// <summary> /// 请求的文件类型.(文件或图片) /// </summary> public FileType FileType { get; set; } #region IActionFilter 成员 void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { HttpContextBase httpContext = filterContext.HttpContext; if (null != httpContext.Request.UrlReferrer) { string serverDomain = httpContext.Request.Url.Host; string refDomain = httpContext.Request.UrlReferrer.Host; if (GetRootDomain(refDomain).Equals(GetRootDomain(serverDomain), StringComparison.OrdinalIgnoreCase)) { return;//如果根域名相同就返回 } } ContentResult cr = new ContentResult(); if (FileType == FileType.Image) { cr.ContentType = "image/jpeg"; FileInfo fi = new FileInfo(httpContext.Server.MapPath("~/Content/images/outsitelink.jpg")); if (fi.Exists) { httpContext.Response.WriteFile(fi.FullName); } else { Bitmap bmp = new Bitmap(200, 50); Graphics g = Graphics.FromImage(bmp); g.FillRectangle(Brushes.White, 0, 0, 200, 50); g.DrawString("请不要盗链", new Font("Arial", 15), Brushes.Red, new PointF(0, 0)); bmp.Save(httpContext.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif); } } else { cr.ContentType = "text/html"; cr.Content = string.Format("请不要盗链。返回<a href=‘{0}‘>{1}</a>", Utils.AbsoluteWebRoot, BlogSettings.Instance.Name); } //将当前的上下文的ActionResult设置为我们的cr(ContentResult) filterContext.Result = cr; } #endregion //// <summary> /// 获取网站的根域名 /// </summary> /// <param name="domain">网站的域名,不带"Http://"</param> /// <returns></returns> private string GetRootDomain(string domain) { if (string.IsNullOrEmpty(domain)) { throw new ArgumentNullException("参数‘domain‘不能为空"); } string[] arr = domain.Split(new[] { ‘.‘ }, StringSplitOptions.RemoveEmptyEntries); if (arr.Length <= 2) { return domain; } else { return arr[arr.Length - 2] + "." + arr[arr.Length - 1]; } } } public enum FileType { File = 1, Image }
然后我们建立一个用于处理文件请求的Controller,并应用上我们刚才建立的Filter:
public class FilesController : BaseController { [AntiOutSiteLink(FileType.Image)] public ActionResult Image(string file) { return Content("Image From 4mvc"); } [AntiOutSiteLink(FileType.File)] public ActionResult File(string file) { return Content("File From 4mvc"); } }
测试结果:
对于ActionFilter的应用是很广泛的,需要灵活运用。对于其他应用,可以参考ASP.NET MVC Action Filter - 缓存与压缩 这一篇文章。
时间: 2024-10-24 14:59:06