ASP.NET MVC 通過ActionFilterAttribute來實現防止重複提交

來源:互聯網
上載者:User

標籤:net   cut   asp.net   mic   路由   gets   bom   exce   ret   

實現思想:每個頁面開啟的時候會在頁面的隱藏控制項自動產生一個值並將這個值賦值session,當提交方法的時候會在過濾器的時候進行擷取session和頁面傳值過來的隱藏控制項的值進行比較,如果值相同的話,重寫session值。否則的話給出提示。

ActionFilter:

using System;
using System.Web;
using System.Web.Mvc;
using EwayFramework.Utils.Token;

namespace EwayFramework.BaseController.Filter
{

/// <summary>
/// 防止重複提交
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class CurrentApproveActionFilterAttribute : ActionFilterAttribute
{
/// <summary>
/// 審批頁面的控制器+Action方法
/// </summary>
public string SessionMyToken { get; set; }
public string ID { get; set; }
public IPageTokenView PageTokenView { get; set; }

/// <summary>
/// Called when authorization is required.
/// </summary>
/// <param name="filterContext">The filter context.</param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
PageTokenView = new SessionPageTokenView(SessionMyToken + HttpContext.Current.Request.Params[ID]);
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}

if (!PageTokenView.TokensMatch)
{
filterContext.Result = new JsonResult
{
Data = new { Result =false, Message = "該單子已在其它地方開啟,請在最新開啟的頁面審批或者重新整理該頁面!" }
};
}

}
}
}

定義產生隨機碼的介面和實現:

1、IPageTokenView.cs

namespace EwayFramework.Utils.Token
{
public interface IPageTokenView
{
/// <summary>
/// Generates the page token.
/// </summary>
string GeneratePageToken();

/// <summary>
/// Gets the get last page token from Form
/// </summary>
string GetLastPageToken { get; }

/// <summary>
/// Gets a value indicating whether [tokens match].
/// </summary>
/// <value>
/// <c>true</c> if [tokens match]; otherwise, <c>false</c>.
/// </value>
bool TokensMatch { get; }
}
}

2、PageTokenViewBase.cs

namespace EwayFramework.Utils.Token
{
public abstract class PageTokenViewBase : IPageTokenView
{
public static readonly string HiddenTokenName = "hiddenToken";
/// <summary>
/// Generates the page token.
/// </summary>
/// <returns></returns>
public abstract string GeneratePageToken();

/// <summary>
/// Gets the get last page token from Form
/// </summary>
public abstract string GetLastPageToken { get; }

/// <summary>
/// Gets a value indicating whether [tokens match].
/// </summary>
/// <value>
/// <c>true</c> if [tokens match]; otherwise, <c>false</c>.
/// </value>
public abstract bool TokensMatch { get; }

}
}

3、SessionPageTokenView.cs

using System;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace EwayFramework.Utils.Token
{
public class SessionPageTokenView : PageTokenViewBase
{
public string SessionMyToken { get; set; }

public SessionPageTokenView(string sessionmytoken)
{
SessionMyToken = sessionmytoken;
}

#region PageTokenViewBase

/// <summary>
/// Generates the page token.
/// </summary>
/// <returns></returns>
public override string GeneratePageToken()
{
if (HttpContext.Current.Session[SessionMyToken] != null)
{
return HttpContext.Current.Session[SessionMyToken].ToString();
}
else
{
var token = GenerateHashToken();
HttpContext.Current.Session[SessionMyToken] = token;
return token;
}
}

/// <summary>
/// Gets the get last page token from Form
/// </summary>
public override string GetLastPageToken
{
get { return HttpContext.Current.Request.Params[HiddenTokenName]; }
}

/// <summary>
/// Gets a value indicating whether [tokens match].
/// </summary>
/// <value>
/// <c>true</c> if [tokens match]; otherwise, <c>false</c>.
/// </value>
public override bool TokensMatch
{
get
{
string formToken = GetLastPageToken;
if (formToken != null)
{
if (formToken.Equals(GeneratePageToken()))
{
//Refresh token
HttpContext.Current.Session[SessionMyToken] = GenerateHashToken();
return true;
}
}
return false;
}
}

#endregion

#region Private Help Method

/// <summary>
/// Generates the hash token.
/// </summary>
/// <returns></returns>
private string GenerateHashToken()
{
return Encrypt(
HttpContext.Current.Session.SessionID + DateTime.Now.Ticks.ToString());
}

#endregion

public static string Encrypt(string plaintext)
{
string cl1 = plaintext;
string pwd = string.Empty;
MD5 md5 = MD5.Create();
byte[] s = md5.ComputeHash(Encoding.Unicode.GetBytes(cl1));
for (int i = 0; i < s.Length; i++)
{
pwd = pwd + s[i].ToString("X");
}
return pwd;
}
}
}

Htmlhelper:

using System;
using System.Web;
using System.Web.Mvc;

namespace EwayFramework.Utils.Token
{
public static class HtmlTokenHelper
{
/// <summary>
/// 自動產生隱藏控制項
/// </summary>
/// <param name="htmlhelper"></param>
/// <param name="id">表單唯一標識ID</param>
/// <returns></returns>
public static MvcHtmlString GenerateVerficationToken(this HtmlHelper htmlhelper,dynamic id)
{
string formValue = SessionPageTokenView.Encrypt(HttpContext.Current.Session.SessionID + DateTime.Now.Ticks.ToString());
string sessionname = HttpContext.Current.Request.Path + htmlhelper.ViewData[id];
HttpContext.Current.Session[sessionname] = formValue;
string fieldName = PageTokenViewBase.HiddenTokenName;
TagBuilder builder = new TagBuilder("input");
builder.Attributes["type"] = "hidden";
builder.Attributes["name"] = fieldName;
builder.Attributes["value"] = formValue;
return new MvcHtmlString(builder.ToString(TagRenderMode.SelfClosing));
}
}
}

調用和實現:

控制器:

在對應的Action方法上加上下述:

SessionMyToken :觸發該Action方法的頁面路由

ID:該單子的唯一標識ID(Action方法的參數必須有對應的值)

  [CurrentApproveActionFilter(SessionMyToken = "/PPHVPM_SecondForecastBOM/SecondForecastBOMPending_P", ID = "MainId")]

頁面:

參數值為:該頁面的唯一標識的 ViewBag.MainId不為空白

 @Html.GenerateVerficationToken("MainId")

ASP.NET MVC 通過ActionFilterAttribute來實現防止重複提交

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.