There are two interfaces related to ActionFilter:
□Iactionfilter: Before and After action execution
Void OnActionExecuting (ActionExecutingContext filterContext );
You can process the request here, or even open a new request.
Void OnActionExecuted (ActonExecutedContext filterContext );
You can process or even cancel the returned results here.
There are two common ActionExecutingContext and ActonExecutedContext parameters:
Are inherited from ControllerContext.
All have the ActionDescriptor attribute: provide the details of the action
All have the ActionResult attribute: cancels the entire request when it is set to null.
Unique to ActonExecutedContext:
Canceled attribute: bool type, whether ActionExecutedContext is Canceled by other action Filters
Exception attribute: Exception thrown by action filter and action
ExceptionHandled property: bool type, whether the exception is handled
□Iresultfilter process the results returned by the action
The method and attribute are similar to that of IActionFilter.
Void OnResultExecuted (ResultExecutedContext filterContext );
Void OnResultExecuting (ResultExecutingContext filterContext );
Instance: inherits ActionFilterAttribute to encrypt the logon Password
ActionFilterAttribute contains the following four methods:
Void OnActionExecuting (ActionExecutingContext filterContext );
Void OnActionExecuted (ActonExecutedContext filterContext );
Void OnResultExecuted (ResultExecutedContext filterContext );
Void OnResultExecuting (ResultExecutingContext filterContext );
Therefore, we can override these four methods in the derived class.
□Ideas
→ Encrypt the password before executing the action
→ After the action is executed, you can decide whether to return success or log on again based on whether the logon is successful.
→ Append some content after the action returns the result
□Inherit ActionFilterAttribute
using System;
using System.Security.Cryptography;
using System.Text;
using System.Web.Mvc;
using System.Web.Security;
namespace MvcApplication1.Extension
{
public class EncryptLoginAttribute : ActionFilterAttribute
{
private string username;
private string password;
private bool isAuthorized = false;
private string longdate;
private string lastTry;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
username = filterContext.HttpContext.Request.Form["username"];
password = filterContext.HttpContext.Request.Form["password"];
MD5 md5Hash = MD5.Create();
string md5Password = GetMD5Hash(md5Hash, password);
bool result = Membership.ValidateUser(username, md5Password);
if (result)
{
FormsAuthentication.SetAuthCookie(username, false);
isAuthorized = true;
longdate = DateTime.Now.ToLongDateString();
}
else
{
isAuthorized = false;
lastTry = DateTime.Now.ToShortDateString() + "-" + DateTime.Now.ToShortTimeString();
}
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (isAuthorized)
{
filterContext.Result = new ViewResult(){ViewName = "Welcome"};
}
else
{
ViewResult result = new ViewResult();
result.ViewName = "Index";
result.ViewBag.message = "Login fail";
filterContext.Result = result;
}
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (filterContext.Exception == null && !filterContext.Canceled)
{
ViewResult result = (ViewResult)filterContext.Result;
if (result != null)
{
if (result.ViewName == "Welcome")
{
filterContext.HttpContext.Response.Write("<p style='color:Green;'><br/>Today is "
+ longdate + "<br/></p>");
}
else if (result.ViewName == "Index")
{
filterContext.HttpContext.Response.Write("<p style='color:Red;'><br />Last Login attemp at "+lastTry+"<br/></p>");
}
filterContext.Result = result;
}
}
}
private static string GetMD5Hash(MD5 md5Hash, string input)
{
//string→byte[]
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder stringBuilder = new StringBuilder();
foreach (byte b in data)
{
stringBuilder.Append(b.ToString("x2"));
}
return stringBuilder.ToString();
}
}
}
□Homecontroller
using System.Web.Mvc;
using System.Web.Security;
using MvcApplication1.Extension;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
[EncryptLogin]
public ActionResult Login(string username, string password)
{
// TODO: Save to database
return null;
}
public ActionResult SignOut()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index");
}
}
}
□Home/Index. cshtml: logon page
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<p style="color: red;">@ViewBag.message</p>
@using (Html.BeginForm("Login", "Home", FormMethod.Post, new {id = "loginForm"}))
{
<p>
Username: @ Html. TextBox ("username", null, new {style = "width: 100px "})
</p>
<p>
Password: @ Html. password ("Password", null, new {style = "width: 100px "})
</p>
<p>
<Input type = "submit" name = "login" value = "Logon"/>
</p>
}
□Web. config Configuration
<Authentication mode = "Forms">
<Forms loginUrl = "~ /Home/Index "timeout =" 2880 ">
<Credentials passwordFormat = "Clear">
<User name = "name" password = "21218cca77804d2ba1922c33e0151105"/>
</Credentials>
</Forms>
</Authentication>
□Logon success view:/Shared/Welcome. cshtml
@{
ViewBag. Title = "Welcome ";
Layout = "~ /Views/Shared/_ Layout. cshtml ";
}
<H2> logon successful ~~ </H2>
@ Html. ActionLink ("logout", "SignOut", "Home ")
Logon page:
Logon Failed:
□If you want to use it globally
Filters. Add (new EncryptLoginAttribute ());
□Remarks
The logon success page is not debugged yet, because when FormsAuthentication is used. authenticate (username, md5Password) indicates that this method is out of date and Membership is used. validateUser (username, md5Password), the corresponding Web. how to configure config is not detailed for the moment.
References:
MVC Filters Part 3-Action Filter and Action Result Filter