有时候,当用户请求一个Controller下的Action,我们希望,在单位时间间隔内,比如每秒,每分钟,每小时,每天,每星期,限制同一个IP地址对某个Action的请求次数。如何做呢?

stefanprodan的MvcThrottle能很好地解决这个问题,以及其它类型的IP限制问题。在这里:https://github.com/stefanprodan/MvcThrottle

把项目从GitHub下载下来,在本地打开。

找到MvcThrottle类库,打开ThrottlingFilter这个类,在该类的OnActionExecuting方法中修改如下:

                        //check if limit is reached
                        if (rateLimit > 0 && throttleCounter.TotalRequests > rateLimit)
                        {
                            //log blocked request
                            if (Logger != null) Logger.Log(ComputeLogEntry(requestId, identity, throttleCounter, rateLimitPeriod.ToString(), rateLimit, filterContext.HttpContext.Request));

                            //break execution and return 409
                            var message = string.IsNullOrEmpty(QuotaExceededMessage) ?
                                "HTTP request quota exceeded! maximum admitted {0} per {1}" : QuotaExceededMessage;

                            //add status code and retry after x seconds to response
                            filterContext.HttpContext.Response.StatusCode = (int)QuotaExceededResponseCode;
                            filterContext.HttpContext.Response.Headers.Set("Retry-After", RetryAfterFrom(throttleCounter.Timestamp, rateLimitPeriod));

                            filterContext.Result = QuotaExceededResult(
                                filterContext.RequestContext,
                                string.Format(message, rateLimit, rateLimitPeriod),
                                QuotaExceededResponseCode,
                                requestId);

                            return;
                        }


把以上替换成

                        //check if limit is reached
                        if (rateLimit > 0 && throttleCounter.TotalRequests > rateLimit)
                        {
                            filterContext.HttpContext.Response.Redirect("/Error.html");
                            return;
                        }  

让其在超过次数时,跳转到项目根目录下的Error.html文件。

生成该类库,类库MvcThrottle.dll生成在类库的bin/Debug文件夹下。

在ASP.NET MVC 4 下创建一个项目。

在项目根目录下创建一个Library文件夹,把刚才的MvcThrottle.dll拷贝其中。

引用Library文件夹下的MvcThrottle.dll组件。

在App_Start文件夹中,修改FilterConfig类如下:

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            var throttleFilter = new ThrottlingFilter
            {
                Policy = new ThrottlePolicy(perSecond: 1, perMinute: 10, perHour: 60 * 10, perDay: 600 * 10)
                {
                    IpThrottling = true
                },
                Repository = new CacheRepository()
            };

            filters.Add(throttleFilter);
        }
    }

创建HomeController,编写如下:

    public class HomeController : Controller
    {

        public ActionResult Index()
        {
            return View();
        }

        [EnableThrottling(PerSecond = 2, PerMinute = 5, PerHour = 30, PerDay = 300)]
        public ActionResult Other()
        {
            return View();
        }

        [HttpPost]
        [EnableThrottling(PerSecond = 2, PerMinute = 5, PerHour = 30, PerDay = 300)]
        public ActionResult GetSth()
        {
            return Json(new {msg=true});
        }
    }


生成解决方案。

报错了!What Happened?

原来MvcThrottle是ASP.NET MVC 5下开发的。

有办法。重新打开MvcThrottle项目的类库,在引用中删除原来的System.Web.Mvc,重新引用本地ASP.NET MVC4版本,重新引用本地的System.Web.Mvc。

重新生成类库,重新拷贝到Library文件夹下,成功生成解决方案。

在Home/Index.cshtml视图中:

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

<input type="button" id="btn" value="请求"/>

@section scripts
{
    <script type="text/javascript">
        $(function() {
            $('#btn').on("click", function() {
                $.post('@Url.Action("GetSth")',function(data) {
                    if (data.msg) {
                        alert("请求成功一次");
                    } else {
                        alert("请求次数过多");
                    }
                });
            });
        });
    </script>
}


当在单位时间间隔内超过规定次数,就弹出"请求次数过多"提示框。

在Home/Other.cshtml视图中:

@{
    ViewBag.Title = "Other";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Other</h2>

当在单位时间间隔内超过规定次数,就跳转到预定的Error.html页了。

在ASP.NET MVC下限制同一个IP地址单位时间间隔内的请求次数的更多相关文章

  1. 在ASP.NET MVC下通过短信验证码注册

    以前发短信使用过短信猫,现在,更多地是使用第三方API.大致过程是: → 用户在页面输入手机号码→ 用户点击"获取验证码"按钮,把手机号码发送给服务端,服务端产生几位数的随机码,并 ...

  2. ASP.NET MVC下的四种验证编程方式

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效性,我们将针对参数的验证成为Model绑定 ...

  3. ASP.NET MVC下的四种验证编程方式【转】

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效 性,我们将针对参数的验证成为Model绑 ...

  4. ASP.NET MVC下的四种验证编程方式[续篇]

    在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式("手工验证"."标注Validation ...

  5. Response.End()在Webform和ASP.NET MVC下的表现差异

    前几天在博问中看到一个问题--Response.End()后,是否停止执行?MVC与WebForm不一致.看到LZ的描述后,虽然奇怪于为何用Response.End()而不用return方式去控制流程 ...

  6. ASP.NET MVC下的四种验证编程方式[续篇]【转】

    在<ASP.NET MVC下的四种验证编程方式> 一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式(“手工验证”.“标注ValidationAttribute特性”.“ ...

  7. ASP.NET MVC下使用AngularJs语言(六):获取下拉列表的value和Text

    前面Insus.NET有在Angularjs实现DropDownList的下拉列表的功能.但是没有实现怎样获取下拉列表的value和text功能. 下面分别使用ng-click和ng-change来实 ...

  8. ASP.NET MVC下使用AngularJs语言(五):ng-selected

    这次学习ng-selected语法,这个是为DropDownList下拉列表显示默认选项. 演示从下面步骤开始 1,新建一个model: 上面#14行代码的property,数据类型为bool.即是存 ...

  9. ASP.NET MVC下使用AngularJs语言(二):ng-click事件

    程序用户交互,用户使用mouse点击,这是一个普通的功能. 在angularjs的铵钮点击命令是ng-click. 创建Angularjs的app使用前一篇<ASP.NET MVC下使用Angu ...

随机推荐

  1. TAU调研咨询

    厦门宇能科技有限公司 GPRS-RTU/DTU.3/4G路由器.无线远程抄表.管网监控 咨询电话:0592-5710250 2017-07-04 9:36:16 您好,欢迎光临.请问有什么可以帮到您? ...

  2. 前后端分离之mockjs基本介绍

    安装与使用 # 安装 npm install mockjs #使用 Mock var Mock = require('mockjs') var data = Mock.mock({ // 属性 lis ...

  3. mavean导入本地仓库

    当你刚开始用mavean的时候可能还没有发现mavean导入本地仓库方法的重要性,但是随着经常使用mavean项目就会发现,有些jar包mavean从网上的mavean仓库中无法导入,例如oracle ...

  4. SRILM Ngram 折扣平滑算法

    关于n-gram 语言模型,大部分在这篇博客里 记过了,   SRILM 语言模型格式解读 , 其实看完了,ngram的大概用法都比较清楚了, 但是关于平滑算法,一直很模糊,就晓得一个"劫富 ...

  5. 【Java】 大话数据结构(18) 排序算法(5) (直接插入排序)

    本文根据<大话数据结构>一书,实现了Java版的直接插入排序. 更多:数据结构与算法合集 基本概念 直接插入排序思路:类似扑克牌的排序过程,从左到右依次遍历,如果遇到一个数小于前一个数,则 ...

  6. javascript编写带阴历的黄历

    最近在做一个黄历的快应用(quickapp),需要涉及到公历转阴历,效果如下: 快应用(https://www.quickapp.cn/): 快应用是基于手机硬件平台的新型应用形态:标准是由主流手机厂 ...

  7. html5 利用谷歌地图显示当前位置

    目前,google在国内需要FQ才能上,翻不了墙的话,只能获取到经纬度信息. *调用navigator.geolocation对象时,首先要获取用户同意. navigator.geolocation. ...

  8. python的异常处理及异常类定义

    python的异常处理语法和大多数语言相似: try: try块的语句... except exceptiontype1 as var:#使用as语句获得本次捕获到的异常的实例var except块语 ...

  9. Linux驱动之串口(UART)

    <uart驱动程序概述> 在嵌入式Linux系统中,串口被看成终端设备,终端设备(tty)的驱动程序分为3部分: tty_core tty_disicipline  tty_driver ...

  10. android touch事件分发流程

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 三个方法:分发触摸事件dispatchTouchEvent.在触摸事件的时候onTouc ...