Asp.Net MVC4.0學習之六--查看Edit方法和Edit視圖

在這節課程中,你將查看爲影片控制器生成的方法和視圖。

運行程序,在瀏覽器中訪問/Movies。鼠標懸停在影片列表某條記錄的Edit鏈接上方,會看到鏈接類似於http://localhost:5279/Movies/Edit/1

Edit的鏈接是由Views\Movies\Index.cshtml文件中的Html.ActionLink方法生成的,如下所示:@Html.ActionLink("Edit", "Edit", new { id=item.ID })

Html對象是System.Web.Mvc.WebViewPage基類暴露出來的一個屬性,作爲助手來使用。助手的ActionLink方法令動態生成與控制器中的方法關聯的HTML超鏈接變得容易。ActionLink的第一個參數是顯示的文本(例如,<a>編輯</a>)。第二個參數是要調用的方法名。最後一個參數是生成的匿名路由數據對象(在這個例子中,是指值爲1的ID)。

在上面生成的鏈接地址是http://localhost:5279/Movies/Edit/1。默認路由(在App_Start\RouteConfig.cs中創建)解析URL的模式爲{controller}/{action}/{id}。因此,ASP.NET將http://localhost:5279/Movies/Edit/1轉換成Movies控制器的Edit方法的請求,並攜帶一個值爲1參數ID。在App_Start\RouteConfig.cs文件中查看以下代碼:

複製代碼
    public class RouteConfig
    {
        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 }
            );
        }
    }
複製代碼

你也可以使用查詢字符串來傳遞方法參數。例如,http://localhost:5279/Movies/Edit?ID=1同樣傳遞值爲1的ID參數給Movies控制器的Edit方法。

打開Movies控制器文件。兩個Edit方法如下所示:

複製代碼
        //
        // GET: /Movies/Edit/5
        public ActionResult Edit(int id = 0)
        {
            Movie movie = db.Movies.Find(id);
            if (movie == null)
            {
                return HttpNotFound();
            }
            return View(movie);
        }
        //
        // POST: /Movies/Edit/5
        [HttpPost]
        public ActionResult Edit(Movie movie)
        {
            if (ModelState.IsValid)
            {
                db.Entry(movie).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(movie);
        }
複製代碼

注意第二個Edit方法前面加了HttpPost屬性。該屬性指定這個重載的Edit方法僅在接受Post請求時被調用。你可以將HttpGet屬性應用在第一個Edit方法,但那不是必須的,因爲它是默認的。(我們將爲HttpGet方法隱性地指定HttpGet屬性)。
HttpGet屬性的Edit方法獲取影片ID參數,使用Entity Framework的Find方法查找影片,並返回選中的影片給Edit視圖。當Edit方法被調用時沒有參數傳入時,ID參數指定0作爲默認值。當無法找到影片時,返回HttpNotFound。當腳手架系統創建Edit視圖時,查看Movie類併爲該類的每個屬性創建<label>和<input>元素。下面的例子展示了生成的Edit視圖:

複製代碼
@model MvcMovie.Models.Movie

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Movie</legend>

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

        <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.Genra)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Genra)
            @Html.ValidationMessageFor(model => model.Genra)
        </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.Date)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Date)
            @Html.ValidationMessageFor(model => model.Date)
        </div>

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

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
複製代碼

注意該視圖模板在文件頂部有@model MvcMovie.Models.Movie語句--指定了視圖期望的模型是Movie類型。
腳手架代碼使用幾個Helper方法來生成流式的Html標記。Html.LabelFor顯示字段名稱(片名、價格、風格等)。Html.EditorFor生成<input>元素。Html.ValidationMessageFor展示與屬性關聯的驗證信息。
運行程序,導航到/Movies 地址。點擊Edit超鏈接。在瀏覽器中查看頁面源代碼。表單元素的Html源碼如下所示:

複製代碼
<!DOCTYPE html>
<html lang="zh">
    <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <meta charset="utf-8" />
        <title>Edit - 電影應用程序</title>
        <link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />
        <link href="/Content/site.css" rel="stylesheet"/>

        <script src="/Scripts/modernizr-2.5.3.js"></script>

    </head>
    <body>
        <header>
            <div class="content-wrapper">
                <div class="float-left">
                    <p class="site-title"><a href="/">MVC 電影</a></p>
                </div>
                <div class="float-right">
                    <section id="login">
                            <ul>
        <li><a href="/Account/Register" id="registerLink">註冊</a></li>
        <li><a href="/Account/Login" id="loginLink">登錄</a></li>
    </ul>

                    </section>
                    <nav>
                        <ul id="menu">
                            <li><a href="/">主頁</a></li>
                            <li><a href="/Home/About">關於</a></li>
                            <li><a href="/Home/Contact">聯繫方式</a></li>
                        </ul>
                    </nav>
                </div>
            </div>
        </header>
        <div id="body">
            
            <section class="content-wrapper main-content clear-fix">
                

<h2>Edit</h2>

<form action="/Movies/Edit/1" method="post">    <fieldset>
        <legend>Movie</legend>

        <input data-val="true" data-val-number="字段 ID 必須是一個數字。" data-val-required="ID 字段是必需的。" id="ID" name="ID" type="hidden" value="1" />

        <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="少年派的奇幻之旅" />
            <span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
        </div>

        <div class="editor-label">
            <label for="Genra">Genra</label>
        </div>
        <div class="editor-field">
            <input class="text-box single-line" id="Genra" name="Genra" type="text" value="冒險" />
            <span class="field-validation-valid" data-valmsg-for="Genra" 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="60.96" />
            <span class="field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
        </div>

        <div class="editor-label">
            <label for="Date">Date</label>
        </div>
        <div class="editor-field">
            <input class="text-box single-line" data-val="true" data-val-date="字段 Date 必須是日期。" data-val-required="Date 字段是必需的。" id="Date" name="Date" type="datetime" value="2012/12/5 0:00:00" />
            <span class="field-validation-valid" data-valmsg-for="Date" data-valmsg-replace="true"></span>
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
</form>
<div>
    <a href="/Movies">Back to List</a>
</div>


            </section>
        </div>
        <footer>
            <div class="content-wrapper">
                <div class="float-left">
                    <p>&copy; 2012 - 我的 ASP.NET MVC 應用程序</p>
                </div>
            </div>
        </footer>

        <script src="/Scripts/jquery-1.7.1.js"></script>

        
    <script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>


    </body>
</html>
複製代碼


包含<input>元素的HTML <form> 元素的action屬性設置爲/Movies/Edit ,方法爲post。點擊Edit按鈕,表單數據將被post到服務器。
處理Post請求

下面列表顯示了處理HttpPost請求版本的Edit方法

複製代碼
        //
        // POST: /Movies/Edit/5
        [HttpPost]
        public ActionResult Edit(Movie movie)
        {
            if (ModelState.IsValid)
            {
                db.Entry(movie).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(movie);
        }
複製代碼

ASP.NET MVC模型綁定機制獲取post表單值,創建Movie對象作爲參數。ModelState.IsValid方法驗證表單提交的數據可以用來修改(編輯或更新)Movie對象。如果數據有效,則影片數據將被保存到MovieDbContext實例集合中。新的影片數據在調用MovieDbContext的SaveChanges時保存到數據庫。保存完數據後,代碼引導用戶到MoviesController 的Index方法,在那展示包括剛剛修改的影片在內的影片集合。
如果post的數據無效,將在表單中重新顯示。Edit.cshtml視圖模板中的Html.ValidationMessageFor助手負責顯示錯誤信息。

譯者注:原文在該部分有大量篇幅提示在非英語母語國家,使用逗號來替代貨幣中的小數點,來實現JQuery正確驗證數據的目的,與主題無關,在此做刪節處理,有興趣的可以閱讀英文原文。

所有的HttpGet方法遵循相似的模式。獲取一個movie對象(或者對象集合,比如在Index例子中),從模型傳遞到視圖。Create方法傳遞空對象給Create視圖。創建、編輯、刪除或者修改數據等所有操作放在HttpPost重載方法中。在HttpGet方法中修改數據存在安全隱患,詳細信息請查看ASP.NET MVC Tip #46 – Don’t use Delete Links because they create Security Holes。在Get方法中修改數據同樣違法Http最佳實踐以及Rest模式(指定Get請求不應當變更你的應用程序狀態)。換句話說,執行Get操作應該是一個不影響以及不會修改此前數據的安全操作。



譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2804100.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章