2015-01-13 133 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