學習ASP.NET MVC(六)——個人第一個ASP.NET MVC 編輯頁面

      在上一文章中由Entity Framework(實體框架)去實現了對數據庫的CURD操做。在本篇文章中,主要是調試修改自動生成的動做方法和視圖,以及調試編輯功能與編輯功能的Book控制器。html

      首先,在Visual Studio運行一下上次的應用程序,經過瀏覽器訪問http://localhost:36878/Book。將鼠標指針移到瀏覽器中的一個「Edit」連接上,就能夠看到這個「Edit」指向的URL以下圖紅框所示。jquery

 

       「Edit」 連接經過Html.ActionLink方法在瀏覽中生成指向Views\Book\Edit.cshtml 視圖的連接。代碼以下。git

   

  @Html.ActionLink("Edit", "Edit", new { id=item.BookID }) 

 

       如上圖中所示,這個「HTML」對象是經過System.Web.Mvc.WebViewPage基類的屬性暴露出來的。這個ActionLink方法能夠很容易地動態生成一個連接,這個連接指向控制器的一個動做方法。ActionLink方法的第一個參數是顯示連接的文本信息(例如,「Edit」)。第二個參數是指動做方法要調用控制器中的方法名稱。最後一個參數是生成的路由數據(如示例中的ID=8)的一個匿名對象。 github

       在上圖中所示的生成的「Edit」連接是http://localhost:36878/Book/Edit/8。默認路由URL模板是{controller}/{action}/{id}(模板代碼位於App_Start\ RouteConfig.cs)。所以,瀏覽器會發出http://localhost:36878/Book/Edit/8 這個URL請求,同時傳遞參數ID=8給Asp.net MVC的Book控制器的「Edit」方法。下面就是App_Start\ RouteConfig.cs裏面的路由模板設置。web

 

public static void RegisterRoutes(RouteCollection routes)

{

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 

    routes.MapRoute(

        name: "Default",

        url: "{controller}/{action}/{id}",

        defaults: new { controller = "Home", action = "Index", 

            id = UrlParameter.Optional }

    );

}

 

          您還可使用action方法後面帶上查詢參數。例如,URL http://localhost:36878/Book/Edit?ID=8,經過ID=8,把參數ID的數據(8)傳遞給了Book控制器的「Edit」方法。以上兩種方式的執行結果以下圖。數據庫

 

         其次,咱們打開BookController.cs文件,來仔細看看裏面的兩個「Edit」方法。代碼以下所示。瀏覽器

 

//

// GET: /Book/Edit/8
 

        public ActionResult Edit(int id = 0)
        {

            Book book = db.Books.Find(id);

            if (book == null)

            {

                return HttpNotFound();

            }

            return View(book);

        }

//

// POST: /Book/Edit/8
 

        [HttpPost]
        public ActionResult Edit(Book book)
{
if (ModelState.IsValid) { db.Entry(book).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(book); }

 

      請注意,第二個「Edit」方法的上面有一個「HttpPost」屬性。這個屬性指定了此方法只能經過POST請求來調用。也能夠給第一個方法上面加上「HTTPGET」屬性,但這不是必要的,由於HTTPGET屬性是默認的。 Visual Studio將會給全部沒有指明的方法,默認且隱性的分配HTTPGET屬性,這種隱性分配了「HTTPGET」屬性的方法稱爲HTTPGET操做方法。) 
        第一個「HTTPGET」的「 Edit」方法是將書籍的ID作爲參數,使用Entity Framework查找方法找到指定ID的書籍,並返回找到的書籍數據給編輯視圖。 此方法中的ID參數被指定了默認值,若是當調用時不帶參數,則ID會使用默認值0。若是書籍記錄沒有找到,將會返回HttpNotFound由基架系統建立的編輯視圖經過<label><input>來呈現Book類中的每一個屬性。示例代碼以下。安全

 

@model MvcApplication1.Models.Book 

@{

    ViewBag.Title = "Edit";
}

<h2>Edit</h2>
 

@using (Html.BeginForm()) {

    @Html.ValidationSummary(true) 

    <fieldset>

        <legend>Book</legend> 

        @Html.HiddenFor(model => model.BookID) 

        <div class="editor-label">

            @Html.LabelFor(model => model.Category)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Category)

            @Html.ValidationMessageFor(model => model.Category)

        </div> 

        <div class="editor-label">

            @Html.LabelFor(model => model.Name)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Name)

            @Html.ValidationMessageFor(model => model.Name)

        </div> 

        <div class="editor-label">

            @Html.LabelFor(model => model.Numberofcopies)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Numberofcopies)

            @Html.ValidationMessageFor(model => model.Numberofcopies)

        </div> 

        <div class="editor-label">

            @Html.LabelFor(model => model.AuthorID)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.AuthorID)

            @Html.ValidationMessageFor(model => model.AuthorID)

        </div> 

        <div class="editor-label">

            @Html.LabelFor(model => model.Price)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Price)

            @Html.ValidationMessageFor(model => model.Price)

        </div> 

        <div class="editor-label">

            @Html.LabelFor(model => model.PublishDate)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.PublishDate)

            @Html.ValidationMessageFor(model => model.PublishDate)

        </div>

        <p>
            <input type="submit" value="Save" />

        </p>

    </fieldset>

}

<div>

    @Html.ActionLink("Back to List", "Index")

</div>

 

@section Scripts {

    @Scripts.Render("~/bundles/jqueryval")

}

 

       請注意,這個視圖模板文件的頂部中有一句@model MvcApplication1.Models.Book,這一句代碼的意思是在文件中聲明瞭對象的類型定義 ——即指定了本視圖中的對象類型是Book。 
       由VS自動生成的基架代碼中使用了幾個輔助方法,這幾個輔助方法用來減小輸入HTML標記。架構

    第一個輔助方法是:Html.LabelFor輔助方法用於顯示字段的名稱(例如:「Name」,「PublishDate」,「Price)。框架

     第二個輔助方法是:Html.EditorFor輔助方法用於自動生成一個HTML<input>元素。

    第三個輔助方法是:Html.ValidationMessageFor輔助方法用於顯示與該屬性關聯的驗證消息。 

 

      再次,按F5運行應用程序,並在瀏覽器中瀏覽/Book網址,在頁面中,使用鼠標左鍵單擊「Edit」連接。瀏覽器會自動導航到編輯頁面,在頁面中,單擊鼠標右鍵,在彈出菜單中選擇「查看源代碼」,你會看到已經生成的HTML表單元素。以下。

     

<form action="/book/Edit/8" method="post">    <fieldset>

        <legend>Book</legend>
 

        <input data-val="true" data-val-number="字段 BookID 必須是一個數字。" data-val-required="BookID 字段是必需的。" id="BookID" 
name
="BookID" type="hidden" value="8" /> <div class="editor-label"> <label for="Category">Category</label> </div> <div class="editor-field"> <input class="text-box single-line" id="Category" name="Category" type="text" value="SAP" /> <span class="field-validation-valid" data-valmsg-for="Category" data-valmsg-replace="true"></span> </div> <div class="editor-label"> <label for="Name">Name</label> </div> <div class="editor-field"> <input class="text-box single-line" id="Name" name="Name" type="text" value="SAP" /> <span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span> </div> <div class="editor-label"> <label for="Numberofcopies">Numberofcopies</label> </div> <div class="editor-field"> <input class="text-box single-line" data-val="true" data-val-number="字段 Numberofcopies 必須是一個數字。"
data-val-required
="Numberofcopies 字段是必需的。" id="Numberofcopies" name="Numberofcopies" type="number" value="12" /> <span class="field-validation-valid" data-valmsg-for="Numberofcopies" data-valmsg-replace="true"></span> </div> <div class="editor-label"> <label for="AuthorID">AuthorID</label> </div> <div class="editor-field"> <input class="text-box single-line" data-val="true" data-val-number="字段 AuthorID 必須是一個數字。"
data-val-required
="AuthorID 字段是必需的。" id="AuthorID" name="AuthorID" type="number" value="12" /> <span class="field-validation-valid" data-valmsg-for="AuthorID" data-valmsg-replace="true"></span> </div> <div class="editor-label"> <label for="Price">Price</label> </div> <div class="editor-field"> <input class="text-box single-line" data-val="true" data-val-number="字段 Price 必須是一個數字。"
data-val-required
="Price 字段是必需的。" id="Price" name="Price" type="text" value="1000000.00" /> <span class="field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span> </div> <div class="editor-label"> <label for="PublishDate">PublishDate</label> </div> <div class="editor-field"> <input class="text-box single-line" data-val="true" data-val-date="字段 PublishDate 必須是日期。"
data-val-required
="PublishDate 字段是必需的。" id="PublishDate" name="PublishDate" type="datetime" value="2013/1/1 0:00:00" /> <span class="field-validation-valid" data-valmsg-for="PublishDate" data-valmsg-replace="true"></span> </div> <p> <input type="submit" value="Save" /> </p> </fieldset> </form>

 

      其中最後一個<input>元素設置爲Submit,用於提交HTML <form>中的表格數據到/Book/Edit URL

 

處理POST請求 
       下面的代碼示例,顯示了Edit操做方法的HttpPost版本。

[HttpPost] 

        public ActionResult Edit(Book book)

        {

            if (ModelState.IsValid)

            {

                db.Entry(book).State = EntityState.Modified;

                db.SaveChanges();

                return RedirectToAction("Index");

            }

            return View(book);

        }

        ASP.NET MVC Model Binder簡單的說就是控制器中的Action方法須要參數數據;而這些參數數據包含在HTTP請求中,包括表單上的ValueURL中的參數等。經過Model Binder的功能將表單上的ValueURL中的參數換成Book對象,而後將Book對象綁定到Action操做方法中的參數上面。其中ModelState.IsValid方法驗證用戶提交的表單中的數據是否能夠被用於修改(編輯或更新)一個Book對象。若是數據是有效的,Book數據將被保存到數據庫的Book集合中(BookDBContext實例)。新的Book數據是經過調用BookDBContextSaveChanges方法保存到數據庫中。保存數據後,代碼將用戶重定向到BookController類的Index操做,同時在瀏覽器中顯示最新的Book列表。 
        若是提交過來的表單中的值是無效的,這些值將從新顯示在瀏覽器的頁面中。在Edit.cshtml視圖模板的Html.ValidationMessageFor助手方法顯示相應的錯誤消息。以下圖。

 

          請注意,ASP.NET MVC 4.0 已經支持jQuery的驗證方法,在非英語語言環境中使用逗號(「,」)代替小數點,你必須包括globalize.js和你本身所須要的特定語言的globalize.cultures.js文件(從https://github.com/ jQuery/ globalize 下載)和JavaScript中使用Globalize.parseFloat。下面的代碼顯示了修改Views\Book\ Edit.cshtml文件中顯示法語(「fr-FR」)

 

@section Scripts {

    @Scripts.Render("~/bundles/jqueryval")

    <script src="~/Scripts/globalize.js"></script>

    <script src="~/Scripts/globalize.culture.fr-FR.js"></script>

    <script>

        $.validator.methods.number = function (value, element) {

            return this.optional(element) ||

                !isNaN(Globalize.parseFloat(value));

        }

        $(document).ready(function () {

            Globalize.culture('fr-FR');

        });

    </script>

    <script>

        jQuery.extend(jQuery.validator.methods, {    

            range: function (value, element, param) {        

                //Use the Globalization plugin to parse the value        

                var val = $.global.parseFloat(value);

                return this.optional(element) || (

                    val >= param[0] && val <= param[1]);

            }

        });

    </script>

}

 

         小數字段可能須要使用一個逗號,不是小數點。做爲一個臨時的解決辦法,你能夠在全球化的元素添加到項目的根目錄下的Web.config文件中。下面的代碼顯示了全球化設置爲en-US」

  <system.web>

    <globalization culture ="en-US" />

    <!--elements removed for clarity-->

  </system.web>

 

      說明:全部的建立,編輯,刪除或以其餘方式修改數據的方法都是經過HttpPost將數據傳給相應控制器的相應方法。

               HTTPGET方法遵循相似的模式。他們獲取一個書籍(Book)對象(或是對象列表,在Index方法狀況下) ,同時將對象數據傳遞給視圖,由視圖進行呈現。 Create方法傳遞一個空的書籍對象給Create視圖。經過HTTP GET式修改數據存在一個安全隱患。使用GET方法修改數據也違反了HTTP的最佳實踐和REST的架構模式,它指定了GET請求不該該改變你的應用程序的狀態。換句話說,執行GET操做應該是一個安全的操做,沒有任何反作用,不會修改你的持久化的數據。

相關文章
相關標籤/搜索