ASP.Net MVC實作表單送出功能(使用AJAX)

表單送出是網頁很常用到的功能,最近剛好有接觸到一個比較簡單的實際案例,順便把它紀錄下來,簡單的描述一下.Net MVC怎麼實作表單送出的功能

完成結果大概如下:

主畫面點選New Item後會彈跳出Dialog視窗,可以在子畫面輸入資料,以及上傳附件,按下子畫面的Add Item按鈕後會把彈跳視窗填寫的資料加入至主畫面的資料列,並可以再做資料的編輯或刪除,填寫完驗證碼以及點擊Submit後即把資料送至後端程式,完成整個表單送出的流程。

在這篇文章中先不討論切版以及RWD的部分,單純只記錄怎樣把前端資料傳到後端去,這裡我們採用AJAX Post的方式。整理下後大致有下列幾個動作

1.建立Js變數,有幾個較重要的變數如下,分別為
data:
因為我們最終目的就是要在前端產生資料post給後端,沒有一致的資料格式,就算資料內容都準備好了,丟給後台的Action時,會因為傳過去的資料跟後台Action的Model參數格式Binding不起來,而導致後端接到的參數內容一直為null,下圖中data變數即為到時要給後端Action的參數(把ViewModel轉成json字串格式後,存放到Js變數裡的時候會自動被轉為Js物件,所以data裡最後存放的不會是Json字串,而是一個Js 物件,可以參考圖2.會比較好懂我要表達的意思),把ViewModel轉成Js物件後就能做很多應用了。
item_data:
item_data這個物件主要是暫時存放子畫面每筆資料的相關資訊,會與後台Model FastRequestItem的欄位做Binding。另外一個原因是因為JQuery不像Angular或Vue可以做到雙向綁定,所以我們大部分都是把使用者key in的資料先存放在自訂物件裡面,再透過JQuery來取得物件內的資料,並顯示於input中,來達到類似雙向綁定的功能。

圖1.
圖2. 1為json字串,2為Js物件

2.建立彈跳視窗內容:
其實彈跳出來的子視窗是一個用bootstrap的Modal(模態框)套件,我們把它做成一個Partialview,這裡我們會針對比較複雜的上傳檔案的部分來講解。

上傳部分HTML如下:
主要是寫在form表單裡面,並且搭配Jquery套件(Query.form.js介紹)在檔案選好時透過ajaxSubmit()去觸發Submit的動作來提交資料

上傳部分JS如下:
我們會在js的$(document).ready()裡面先綁定一個change事件,等user選定好檔案後就會觸發Query.form.js套件的Ajaxsubmit()來自動post資料。原本我是把change事件直接在HTML標籤裡面加一個OnChange屬性,並在裡面直接call filechange這個Js function,但後來經同事提醒,在HTML標籤裡直接寫JS語法會有XSS攻擊的問題,所以就把它改成事件監聽的方式來做觸法,之後的OnClick也是一樣的做法

下面把比較重要的部份用紅框框起來。

1.第一個紅框是因為由於我們觸發ajaxSubmit用的是change事件(請參考上圖),如過上傳檔名一樣的同一份檔案的話,因為沒有change就不會觸發上傳行為了,所以要在每一次上傳檔案時把value值清空(用element.value = null也可以)。

2.第二個框框就是自動change事件觸發時會自動幫你打ajax到後端

3.第三個框框就是上傳成功後要先宣告一個空的Files陣列來裝上傳的資料的相關資訊,Files裡面的屬性成員名稱也不能亂取,跟後端Model File的屬性名稱都是要對應一致的

 

Files物件裡面有資料後,就可以執行refresh_file_list_event()這個function,來更新彈跳視窗中的檔案上傳列表畫面了。js程式碼如下,主要是透過跑迴圈讀取Files物件裡面的東西再用拼字串的方式,最後在append到table標籤裡面(也可以使用.html())

檔案上傳後的完成圖如下:
 

 

3.綁定檔案刪除事件:
可以看到上一步我在拼上傳檔案清單的<tr>字串時,在a這個標籤裡增加了一個class:delete_upload_file,新增這個class的用意在於我們必須要用這個class來做JQuery click事件的綁定,js程式部分如下圖,並把比較重要的部份用紅框框起來。

1.第一個紅框是因為由於我們在綁定JQuery事件時,如果要綁定的物件還沒有動態產生,就要先綁定在已經存在的母元素上(直接綁在body也可以,body一定會存在)。

2.第二個框框主要是設定替class為delete_upload_file的物件綁定click事件

3.第三個框框內容是在處理刪除檔案的主要邏輯,我們取得點選的檔案的那列<tr>的index後,再透過此index去Files物件做splice刪除的動作,刪除完Files陣列裡面的檔案後,執行refresh_file_list_event()來更新檔案清單

 

4.綁定Add Item事件:
當我們按下Add Item按鈕後,會把我們在Modal彈跳視窗裡所進行的資料異動紀錄(上傳的檔案的相關訊息 & input輸入的資料)原本存放在item_data裡的資料push或是賦值到data.Order.Assets裡面。簡單來說,item_data只會存放當下Modal視窗裡的單筆資料的相關資訊,data則是會存放我們所有在Modal彈跳視窗裡的紀錄,js程式部分如下圖,並把比較重要的部份用紅框框起來。

1.設定變數item_data

2.由變數insertflag來判斷此異動是新增/編輯,新增我們就把item_data的資料push到跟Model格式有mapping的data.Order.Assets裡

 

完成上述的步驟後,Modal彈跳視窗裡的事件大致都完成得差不多了。彈跳Modal視窗裡的相關資訊都已經存放到data物件裡面了,data物件是一個跟Action的參數Model格式一致的Js物件,所以到時我們可以直接post data物件給後端,.Net會自動Binding。

先給大家看一下後端的Action,可以看到這個Action需要三個參數,其中第一個參數是要接收一個類別物件(Model),裡面主要紀錄的是我們在前端畫面輸入的資料。

接著來看前端的AJAX如何post資料給後端,AJAX第一個參數就是我們的data.Order(可以再自己依照商業邏輯進行內容異動,總之原則就是最後data物件的資料結構一定要能跟Action第一個(Model)參數的結構能夠Binding的起來),資料成功post到後端後,就端看各位如何進行db異動啦

 

以上是一個網頁表單從前端資料輸入,並post使用者key in的資料到後端的大致流程,因為裡面有些公司商業邏輯,也沒有辦法寫得太詳細,再請見諒,但有問題可以於下方留言喔。

表單驗證的部分可以參考:
jQuery Validation Plugin + jQuery.validate.unobtrusive + AJAX,不透過form submit來做網頁表單驗證