2015-01-13 96 views
0

我希望关于我打算使用用于防止在ASP.NET MVC 4应用程序重复记录的方法的一些反馈,并影响敲我没有的,虽然为用户体验。防止双提交/后ASP.NET MVC页

的web表单具有六个输入字段和保存按钮(以及取消按钮),用户可以利用长达10分钟的形式填充。

一旦字段通过后的页面上成功/失败重定向到不同的页面,该数据是使用一个新的GUID作为主键记录在数据库表后提交。

要停止用户多次按下保存按钮,但允许浏览器在关闭的连接上重新发布请求,我打算在呈现表单时为新记录主键提供Guid作为隐藏输入字段。

如果重新发布情况,或用户按保存多次,数据库服务器会拒绝,因为重复的键,我可以检查与服务器端处理的记录的第二个职位。

但这是否会给我造成更大的问题?

+0

问题是什么? –

+0

将主键ID放入隐藏字段时唯一的问题是用户可以进入该字段并更改主键并更新数据库中的每条记录。现在,因为它们是Guid的,所以几乎不可能猜到已经使用过的Guid,并且会比之前的用户表单更新,如果你使用的是整数,那么我会这么说是个坏主意 –

+0

你有没有使用过Bootstrap?因为它会自动disabvles按钮一旦点击,如果不使用jquery或一些加载器或隐藏按钮,一旦点击,直到你收到回应的发布请求' – Tushar

回答

1

如果您在窗体中使用隐藏的防伪标记(如您应该那样),则可以在首次提交时缓存防伪标记,并在需要时从缓存中删除标记,或者在缓存项之后过期设定时间量。

然后,您将能够针对缓存检查每个请求是否已提交特定表单并拒绝它(如果有)。

您不需要生成自己的GUID,因为生成防伪标记时已经完成了这个GUID。

0

您可以简单地在客户端处理它。

创建一个叠加的div,以显示没有和大Z索引和jQuery脚本CSS类,显示该div当用户按下提交按钮。

+0

时不时地让用户没有任何前进的方向。表单卡住了,服务器没有找到帖子,他们必须重新输入所有内容。问题是浏览器从不知道服务器是否没有得到POST或者浏览器没有得到响应。 –

+0

如果display设置为none,则不需要大量的z-index。 – Porschiey

+0

@Porschiey是的,但最终你会显示div,当你这样做时,它应该在顶部 – pdeane

0

据我了解,你打算保持主键在一个隐藏的输入,当你最初渲染页面。显然这不是一个好主意。首先,如果您在c#中使用Guid实现,它是字符串并且将字符串作为主键不是一个好主意(See the answer for this SO question)。

您可以通过两种方式解决此问题。首先,在第一次点击时禁用按钮。其次,在不依赖主键的情况下在代码后面构建验证。

+0

你发布了一个关于Guid vs int作为主键聚集索引表现的问题的链接 - 除了事实上他们都提到了Guid –

+0

撇开Guid PK性能问题我知道并采取了这一做法。安全问题也让我担心,但是我一直无法用它来定义一个真正的问题,除了伪造这些条目的人是否有任何链接可以帮助解决这个问题? –

+0

除了性能问题和Guid篡改的可能性之外,这种方法没有问题。事实上,你甚至不需要保持Guid为PK。您可以将Guid与记录一起插入,并检查在插入前是否存在带此Guid的记录。 – su8898

2

如果您愿意,可以使用某些jQuery防止客户端双击。

在你的HTML,有你的提交按钮是这样的:

<a id="submit-button"> Submit Form </a> <span id="working-message"></span> 

在JavaScript(jQuery的):

$('#submit-button').click(function() { 
    $(this).hide(); 
    $('#working-message').html('Working on that...'); 
    $.post('/someurl', formData, function(data) { 
    //success 
    //redirect to all done page 
    }).fail(function(xhr) { 
    $('#submit-button').show(); 
    $('#working-message').html('Submit failed, try again?'); 
    }); 
}); // end on click 

这将隐藏按钮,它甚至尝试提交之前,所以用户不能点击两次。这也显示了进展,并在失败时允许他们重新提交。你可能想考虑在我的上面的代码中添加超时。

另一种选择是使用jquery获取表格$('#form-id').submit(),但你不能像跟我做的ajax调用一样简单地跟踪进度。

编辑: 我仍然建议寻找方法来防止从服务器端立场双重提交,仅出于安全原因。

+0

有趣的是,我没有看过ajax,因为我正在使用ASP.NET MVC 4模式,并且希望保留MVC 4,越来越多地看到它离开MVC4更好。 仍然希望得到一个MVC4答案 –

+0

嘿没问题! :)我在日常工作中广泛使用MVC4和MVC5,但我几乎总是在我的MVC应用程序中使用这种模式来提交表单。它允许更多的灵活性,并且我总是可以使用其他MVC选项来验证数据“服务器端”。看看'JsonResult':你可以在你的MVC应用程序中创建适合这些类型的jQuery/Ajax调用的动作。 – Porschiey