[.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模型模块中添加验证

你可能感兴趣的:(controller)