[.NET MVC4 入門系列04]Controller和View間交互原理


一、Edit Action和其所對應的Edit View:

1.Edit 鏈接:

在Index頁中的Edit鏈接是由代碼生成:@Html.ActionLink("Edit","Edit",new{ id=item.ID })

這個方法來源於 System.Web.Mvc.HtmlHelper.ActionLink(string,string,object)

http://msdn.microsoft.com/en-us/library/ee703457(v=vs.108).aspx

ActionLink(String, String, Object) Overloaded. Returns an anchor element (a element) that contains the virtual path of the specified action. (Defined by LinkExtensions.)

返回一個<a>,包含controller中指定action方法所返回View的虛擬路徑

參數1 string : 超鏈接上顯示的文字

參數2 string : Action的方法名

參數3 object: An object that contains the parameters for a route. The parameters are retrieved through reflection by examining the properties of the object. The object is typically created by using object initializer syntax.

匿名對象,會生成路由數據

2.默認路由(Route)

項目自動生成的默認路由配置代碼\Appstart\RouteConfig.cs :

 1     public class RouteConfig
 2     {
 3         public static void RegisterRoutes(RouteCollection routes)
 4         {
 5             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 6 
 7             routes.MapRoute(
 8                 name: "Default",
 9                 url: "{controller}/{action}/{id}",
10                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
11             );
12         }
13     }

3.Controller中的兩個Edit Action:

 1  //
 2         // GET: /Movies/Edit/5
 3 
 4         public ActionResult Edit(int id = 0)
 5         {
 6             Movie movie = db.Movies.Find(id);
 7             if (movie == null)
 8             {
 9                 return HttpNotFound();
10             }
11             return View(movie);
12         }
13 
14         //
15         // POST: /Movies/Edit/5
16 
17         [HttpPost]
18         [ValidateAntiForgeryToken]
19         public ActionResult Edit(Movie movie)
20         {
21             if (ModelState.IsValid)
22             {
23                 db.Entry(movie).State = EntityState.Modified;
24                 db.SaveChanges();
25                 return RedirectToAction("Index");
26             }
27             return View(movie);
28         }

第二個Edit方法加了[HttpPost] attribute 前綴,限制了當前這個Edit方法重載,只能用來相應POST請求。而對於GET請求,使用第一種Edit方法。

Get請求用來從服務器獲取數據,Post方法用於向服務器提交數據.

這里Get的Edit方法(第一個)執行將數據讀入Edit View的操作;Post的Edit方法(第二個)執行將更改后的數據提交服務器,更新選定的movie。

第一個HttpGet 的Edit方法獲取Movie Id作為參數,使用Entity Framework 的 Find()方法查找到指定的movie對象,並將其返回給Edit View。

所以,

  • 第一個Edit Action Method用來跳轉到Edit View;第一個使用Get請求方式,從服務器獲取視圖;
  • 第二個Edit Action Method用來將更改更新到數據庫;第二個使用Post請求方式,向服務器提交數據,並由服務器處理。

4. Edit View

\Views\Movies\EditView.cshtml

 1 @model MvcApplication1.Models.Movie
 2 
 3 @{
 4     ViewBag.Title = "Edit";
 5 }
 6 
 7 <h2>Edit</h2>
 8 
 9 @using (Html.BeginForm()) {
10     @Html.AntiForgeryToken()
11     @Html.ValidationSummary(true)
12 
13     <fieldset>
14         <legend>Movie</legend>
15 
16         @Html.HiddenFor(model => model.ID)
17 
18         <div class="editor-label">
19             @Html.LabelFor(model => model.Title)
20         </div>
21         <div class="editor-field">
22             @Html.EditorFor(model => model.Title)
23             @Html.ValidationMessageFor(model => model.Title)
24         </div>
25 
26         <div class="editor-label">
27             @Html.LabelFor(model => model.ReleaseDate)
28         </div>
29         <div class="editor-field">
30             @Html.EditorFor(model => model.ReleaseDate)
31             @Html.ValidationMessageFor(model => model.ReleaseDate)
32         </div>
33 
34         <div class="editor-label">
35             @Html.LabelFor(model => model.Genre)
36         </div>
37         <div class="editor-field">
38             @Html.EditorFor(model => model.Genre)
39             @Html.ValidationMessageFor(model => model.Genre)
40         </div>
41 
42         <div class="editor-label">
43             @Html.LabelFor(model => model.Price)
44         </div>
45         <div class="editor-field">
46             @Html.EditorFor(model => model.Price)
47             @Html.ValidationMessageFor(model => model.Price)
48         </div>
49 
50         <p>
51             <input type="submit" value="Save" />
52         </p>
53     </fieldset>
54 }
55 
56 <div>
57     @Html.ActionLink("Back to List", "Index")
58 </div>
59 
60 @section Scripts {
61     @Scripts.Render("~/bundles/jqueryval")
62 }

從代碼中可知,對應每個Movie中的字段,配套一個label和一個input , 如:

18         <div class="editor-label">
19             @Html.LabelFor(model => model.Title)
20         </div>
21         <div class="editor-field">
22             @Html.EditorFor(model => model.Title)
23             @Html.ValidationMessageFor(model => model.Title)
24         </div>

 HtmlHelper 的擴展方法LabelFor,EditorFor和ValidationMessage參數一樣,返回值也類似,如下提示:

5. 處理Post請求 ( processing the post request )

查看第二個Edit Action方法。該方法使用的是Post請求方式([HttpPost]標明)

Asp.net MVC model binder(模型綁定器)接收到以Post請求方式由客戶端發送過來的form信息,並創建一個Movie對象,將其作為Edit Action方法的參數movie。ModelState.IsValid 用於驗證從客戶端瀏覽器獲得的form信息可以用來更改(edit or update)一個Movie對象(Entity Framewor)。這個值若為真,執行if中語句,設置MovieDBContext(Entity FrameWork)可更改,並保存更改后的數據(通過MovieDbContext對象db調用SaveChanges()方法),並將頁面跳轉回Index頁;為假,不做任何更改,提示驗證錯誤(Html.ValidationMessageFor來負責),並還停留在Edit View中。

查看上面帶有[HttpPost]前綴的Edit方法,包含下面幾個知識點:

1)Asp.net Mvc model binder

相關參考:

一篇不錯的博文:http://msdn.microsoft.com/en-us/magazine/hh781022.aspx

msdn:http://msdn.microsoft.com/en-us/library/dd410405(v=vs.100).aspx

System.Web.Mvc.DefaultModelBinder: http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultmodelbinder(v=vs.108).aspx

IModeBinder Interface msdn

Msdn給的概念:

A model binder in MVC provides a simple way to map posted form values to a .NET Framework type and pass the type to an action method as a parameter. Binders also give you control over the deserialization of types that are passed to action methods. Model binders are like type converters, because they can convert HTTP requests into objects that are passed to an action method. However, they also have information about the current controller context.

mvc中的model binder 提供一條單向路徑,將web form中的值(Post方式)提交給一個類對象,並將這個對象以參數形式傳遞給指定的action方法。

model binder 就像是一個類型轉換器,可以將HTTP請求轉換成一個對象,並將其傳輸給一個action方法。

而且,它還包含當前Controller context(上下文)信息。

A model binder lets you associate a class that implements the IModelBinder interface with an action-method parameter or with a type. The IModelBinder interface contains a GetValue method that the framework calls in order to retrieve the value of a specified parameter or type. The DefaultModelBinder class works with most .NET Framework types, including arrays and IListICollection, andIDictionary objects.

 model binder 可已經實現了IModelBinder接口的類和一個action方法參數或類型關聯起來,IModelBinder接口包含一個GetValue方法,通過Framework調用該方法可獲得一個特殊參數/類的值。

 


 

初學MS 的MVC 4,參照微軟www.asp.net/mvc 中的入門項目,寫個MVC 4的入門系列,以供復習和分享。

微軟入門項目:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4

【目錄】

1.[.NET MVC4 入門系列01]Helloworld MVC 4 第一個MVC4程序

2.  [.NET MVC4 入門系列02]MVC Movie 為項目添加Model

3.  [.NET MVC4 入門系列03]使用Controller訪問Model中數據

4.  [.NET MVC4 入門系列04]Controller和View間交互原理

5. .NET MVC4 入門系列05]添加自定義查詢頁Search

6. [.NET MVC4 入門系列06] 在Movie Model和表中添加新字段(Code First Migrations)

7. [.NET MVC4 入門系列07] 在Model模型模塊中添加驗證


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM