ASP.NET MVC 4 實作CRUD Create Ajax

繼上一篇,DataTable  + 搜尋  的AJAX完成後,現在要進入第一個功能,新增。
這一系列的文章會稍微著重在於jQuery 對 Controller的溝通,然而實作功能,請先參閱「ASP.NET MVC 專案分層架構 Part.1 初學者的起手式」Kevin前輩的這篇系列文章再來。

又或者對於MVC,Model、Controll、View之間的關係有一定相當基本的了解,才建議看此篇文章。

雖然說此篇也是個新手文,但沒有寫過一個基本的MVC的朋友,還是先了解一下MVC之間的溝通,再來看此篇文章。
當然文內有任何錯誤或者有更好的方法,希望各位點出來一起討論,或者前輩能指導謝謝。

上一篇「ASP.NET MVC 4 實作PagedList.Mvc + AJAX 搜尋功能」,功能如果做出來沒有問題,我們就接下去做第一個新增的功能。
將新增功能的實作在Services寫好後,在Controller以POST方式寫Action,Controller如下。
 

[HttpPost]
public ActionResult Create(Customers customers)
{
   if (customers != null && ModelState.IsValid)
   {
      this.custromService.Create(customers);
      var returnData = new
      {
         // 成功與否
         IsSuccess = true,
      };
      return Content(Newtonsoft.Json.JsonConvert.SerializeObject(returnData), "application/json"); 
   }
   else
   {
      var returnData = new
      {
         // 成功與否
         IsSuccess = false,
      };

      return Content(Newtonsoft.Json.JsonConvert.SerializeObject(returnData), "application/json"); 
   }
}

來講解一下Controller的部分,這部分有些參考到「[ASP NET MVC] 透過AJAX接收ModelState Errors顯示於對應欄位中」Chris前輩的文章。
等一下再寫前端傳給Action的時候會以POST的方式傳送,而相對的參數會以JSON格式。

所以在此很重要,要讓前端知道有沒有成功,就不能再使用return View之類的指令直接去轉換網址或重新整理網址,這些指令jQuery是不認得的。
回傳的資料理所當然的也會以Json傳給前端的jQuery接收。

此功能要撰寫的程式碼並不複雜,很容易就懂原理,後端大致上這樣就完成拉,然後接下來就是前端的View和jQuery的部分。
先講View的部分,首先因為如果將每一個功能都寫在Index裡面會很大很雜,要找起來就會比較麻煩。

上一篇講的架構是

View
    _DataTable.cshtml <--- PartialView
    Index.cshtml <--主要顯示畫面


在此我們再增加一個部分檢視,View架構就是如下。

View
    _DataTable.cshtml <--- PartialView
    _Create.cshtml <---新增功能的部分檢視
    Index.cshtml <--主要顯示畫面

為什麼要這樣做,另一個原因在於,如果像我這個練習中沒有再多去建設一個ViewModel之下,一個頁面只能使用一個Model就會造成@model PageList<T>和原先的 @model model會有所衝突。

所以我們用了部分檢視,一樣可以呼叫到該頁面的HTML內容也可以針對其座操控。(他與上一章節所用的AJAX傳入的頁面方式不同,所以可以在Index上可以直接看到這部分的HTML Code,但所有的頁面是可會互相影響和操控的。)

講這麼多直接給你看_Create.cshtml的部分。如下

@model Ajax_CRUD_Model.Customers

<div class="modal fade" id="Create" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
                <h3 class="modal-title" id="lineModalLabel">New Customer</h3>
            </div>
            <div class="modal-body">

                <!-- content goes here -->
                <form id="CreateForm">
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.CustomerID)
                        @Html.TextBoxFor(model => model.CustomerID, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.CompanyName)
                        @Html.TextBoxFor(model => model.CompanyName, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.ContactName)
                        @Html.TextBoxFor(model => model.ContactName, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.ContactTitle)
                        @Html.TextBoxFor(model => model.ContactTitle, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.Country)
                        @Html.TextBoxFor(model => model.Country, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.City)
                        @Html.TextBoxFor(model => model.City, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.PostalCode)
                        @Html.TextBoxFor(model => model.PostalCode, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.Phone)
                        @Html.TextBoxFor(model => model.Phone, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.Fax)
                        @Html.TextBoxFor(model => model.Fax, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.Address)
                        @Html.TextBoxFor(model => model.Address, new {@class = "form-control" })
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(model => model.Region)
                        @Html.TextBoxFor(model => model.Region, new {@class = "form-control" })
                    </div>

                </form>
            </div>
            <div class="modal-footer">
                <div class="btn-group btn-group-justified" role="group" aria-label="group button">
                    <div class="btn-group" role="group">
                        <button type="button" class="btn btn-default" data-dismiss="modal" role="button">Close</button>
                    </div>
                    <div class="btn-group" role="group">
                        <button type="submit" onclick="Create()" id="saveImage" class="btn btn-default btn-hover-green" data-action="save" role="button">Save</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

對了,在此先提到顯示頁面的Index.cshtml檔案中要加入此頁面去不然就等於白做工了。如下

<!--加入部分頁面-->
@Html.Partial("~/Views/Customer/_Create.cshtml")

加入上述這段進入Index.cshtml

好了,最後就是jQuery的部分,因為頁面內容不大,所以我喜歡把什麼功能的jQuery加入在相對應的頁面底下。如下

<!--Ajax Create-->
<script>
    function Create() {
        var myForm = $("#CreateForm");
        var dataForm = myForm.serialize();
        var validator = myForm.validate();

        $.ajax({
            type: 'POST',
            url: '@Url.Action("Create", "Customer")',
            data: dataForm,
            cache: false,
            async: false,
            dataType: 'json',
            success: function (data) {
              
                    $('#Create').modal('hide');
                    alert('新增資料成功');
                    var page = window.location.hash
                    ? window.location.hash.slice(1)
                    : 1;
                    fetchPage(page);
            }
        });
    }
</script>

首先取得jQuery表單內容,再以Ajax方式將表單內容傳送到Action處理,結束。
沒錯這裡的jQuery就那麼的簡單,但有幾點要注意的地方,處理完成後Action會回傳資料回來給jQuery,此時要將我們的表單隱藏起來,再來看你要不要跳出什麼成功新增的訊息。
然後最重要的就是,要將DataTable重新整理一遍,也就是要下達一次上一篇所建構的函數fetchPage();

這樣新增的功能就大功告成拉。

然而下一篇我在思考要先講Chris前輩的驗證「[ASP NET MVC] 透過AJAX接收ModelState Errors顯示於對應欄位中」還是把其他功能先講完再回頭來講驗證,就讓我慢慢地思考一下吧。

MVC小菜鳥下台一鞠躬。