前一篇中我們已經了解了Action Filter與內置的Filter實現,現在我們就來 寫一個實例。就寫一個防盜鏈的Filter吧。
首先繼承自FilterAttribute 類同時實現IActionFilter接口,代碼如下:
/**//// <summary>
/// 防盜鏈Filter.
/// </summary>
public class AntiOutSiteLinkAttribute : ActionFilterAttribute, IActionFilter
{
public AntiOutSiteLinkAttribute(FileType fileType)
{
this.FileType = fileType;
}
/**//// <summary>
/// 請求的文件類型.(文件或圖片)
/// </summary>
public FileType FileType { get; set; }
IActionFilter 成員#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
}