首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免在控制器中接收重复请求

如何避免在控制器中接收重复请求
EN

Stack Overflow用户
提问于 2017-08-17 05:00:21
回答 1查看 1.2K关注 0票数 0

我已经构建了增强WebApi服务(MvcApplication)的UserName和电子邮件。

我有这个服务的网址:

代码语言:javascript
复制
Ex: www.domain.com/Controller/SendUser

我有一些分支机构使用这个URL到我的服务在他们的网站/登陆页面,他们发送给我的数据与用户名,和电子邮件的潜在客户。

一些分支机构已经构建了它们提交错误的表单,并允许用户在看到屏幕上的响应或重定向到出现问题的下一个page.And之前多次按“发送”按钮。

我用重复的数据向我的服务发出5-10请求,并开始运行我的所有验证函数和方法插入到数据库。

重要:我不会在数据库级别上解决方案,我想在开始时停止请求,甚至不启动所有的验证服务。

我需要接收请求,临时保存UserName+Email,如果我在相同的秒内或在接下来的10秒内接收到相同的UserName+Email,这只是为了避免它。

我尝试将静态字典添加到Global.asax中并保存EncodedLead(从User+Email),在检查是否ContainsKey(X)之前,我锁定字典GlobalMemoryLeads,而不是添加一个键,但是即使在字典被锁定时,我仍然会遇到一些错误--键已经准备好了。

线程似乎会抛出锁并尝试添加相同的键,即使GlobalMemoryLeads.ContainsKey(EncodedLead)返回false,另一个线程也可以将键添加到被另一个线程锁定的字典中??这里缺少什么?

如何避免重复请求?

已更新

我的代码:

代码语言:javascript
复制
      [AcceptVerbs(WebRequestMethods.Http.Get, WebRequestMethods.Http.Post)]
      [AllowCrossSiteJson]
        public ActionResult SendUser(string UserName, string Email, )
        {
          string response = "";
          bool duplicate=false;
          try
           { 
          string Lead = UserName + email;
          int  EncodedLead = Lead.GetHashCode();

           //here i lock my GlobalMemoryLeads dictionary
        lock (MvcApplication.GlobalMemoryLeads)
           {
            //here i check if that key is all ready ContainsKey
       if (!MvcApplication.GlobalMemoryLeads.ContainsKey(EncodedLead))
           {
              try
              {
                MvcApplication.GlobalMemoryLeads.Add(EncodedLead, false);
              }
         catch (Exception ex)
       {

   //here i get error that key is all ready exist
   //how it possible if i have 
   //1: Globalizes lock
   //2 i check ContainsKey before
    return Json(new { respondNotSuccess = "Duplicate Lead" });
     }

            }

               }

             }
            catch (Exception ex)
            {
                response = "Exception " + ex.Message;

            }

            return Json(new { respondSuccess = response });
        }
EN

回答 1

Stack Overflow用户

发布于 2017-08-22 09:58:37

通常,避免锁定公共类型或代码无法控制的实例。

常见构造lock ( this )、lock (typeof (MyType))和lock ("myLock")违反了这个准则:

  • 如果实例可以公开访问,锁(此)是一个问题。
  • 锁(typeof ( MyType ))是一个问题,如果MyType是可公开访问的。
  • 锁("myLock")是一个问题,因为进程中使用相同字符串的任何其他代码都将共享相同的锁。

最佳实践是定义要锁定的私有对象或私有静态对象变量,以保护所有实例所共有的数据。

试着去做这样的事情:

代码语言:javascript
复制
private Object thisLock = new Object();

lock (thisLock)
   {
      if (!MvcApplication.GlobalMemoryLeads.ContainsKey(EncodedLead))
      {
          try
          {
             MvcApplication.GlobalMemoryLeads.Add(EncodedLead, false);
             ...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45726892

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档