ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

澳门新葡亰平台官网 21

事例1:调用自定义页面分类ID=1的页面导航

图2-10:分类的目录(Index)页面

地方例子是调用分类ID=1的自定义页面,不限制能够去掉SQL中 where
classid=1条件。

  一旦成功增加,成品的目录(Index)页面应如图2-14所示。数据以往也别保存到数据库中,如图2-15。要查看数据库中的数据,能够在SQL
Server对象能源微电脑中右键单击dbo.Products表,然后从菜单中选取【查看数据】菜单项。

[e:loop={'select id,path,title from [!db.pre!]enewspage where classid=1 order by id',20,24,0}]?php$pageurl=$public_r['newsurl'].str_replace('../../','',$bqr['path']);?lia href=?=$pageurl??=$bqr[title]?/a/li[/e:loop]

澳门新葡亰平台官网 1

[e:loop={'select id,path,title from [!db.pre!]enewspage where classid=1 order by id',20,24,0}]?php$pageurl=$public_r['newsurl'].str_replace('../../','',$bqr['path']);$css='pagecss';if($classid=='page'.$bqr[id]){ $css='selfpagecss';}?li class=?=$css?a href=?=$pageurl??=$bqr[title]?/a/li[/e:loop]

  图2-5突显了所生成的HTML页面。下边是上述代码中的一些关键点:

事例2:调用自定义页面导航并识别当前自定义页面

  我们曾经看见什么创立叁个极其基本的页面用于浮现分裂实体的列表。现在,大家将加多一些使得的职能因而让那么些列表实行交互作用。我们将接收分类列表中被增选的值来过滤产物列表。为了达到此指标,大家须求改进下列代码:

咱们做单页(比如集团介绍、联系大家等页面卡塔尔(قطر‎时平日采用自定义页面来做,而调用出自定义页面导航能够用竹签SQL调用。如下:

  从菜单栏中精选【生成实施方案】,然后再选取【调节和测量试验】->【开头实施(不调节和测验卡塔尔国】菜单项来运营应用程序。点击产物链接展开成品目录(Index)页面,大家拜访到多个Name标题现在成为了Category
Name和Product Name,如图2-17所示。

有关认证:

2.5 使用新的付加物和分类视图

2、右击Controllers文件夹,然后接受【增多】->【调节器】。

  • [HttpPost]特色告诉调整器当调用Create动作方法的诉求是多个POST央求时,使用该办法,而不接纳别的重载的Create方法。
  • [ValidateAntiForgeryToken]保障Token通过HTML表单传递,进而证实诉求。那样做的指标是保障哀求确确实实地是源于于大家所愿意的表单,以免御跨站须求捏造。简单的话,跨站供给伪造正是来自于其余站点的表单央浼伪装成咱们友好站点的央浼,进而实践带有恶意目标的操作。
  • 参数([Bind(Include = “ID,Name”)] Category
    category卡塔尔国告诉方法在加上二个新的归类时只含有ID和Name属性。Bind天性使用Include属性创制了贰个平安无事质量列表,独有该列表中的属性允许被涂改,进而防卫overposting攻击。可是,就疑似大家前边探讨的那样,它不像我们所期待的那么行事。由此,大家须要接受一种不一致的法子来管理局地值恐怕为空的编写制定和新建操作。举三个overposting的例子,思谋上边一种情景,当顾客提交一个成品订单的时候,该产物的价格也被交付,overposting攻击会尝试通过买卖二个非常低价格的物品来校勘已经被交给的产物价格。

2.4 加多调整器和视图

.4.3.2
分类的详细情况(Details)视图

1 public ActionResult Index(string category)
2 {
3     var products = db.Products.Include(p => p.Category);
4     if (!string.IsNullOrEmpty(category))
5     {
6         products = products.Where(p => p.Category.Name == category);
7     }
8     return View(products.ToList());
9 }

  为了做到依据分类过滤成品的功力,大家要求改进分类的目录(Index)页面中的成品列表,将其变动为链接到ProductsController的Index方法的超链接。

  • 澳门新葡亰平台官网 ,分拣的目录(Index)视图将会现出。只怕该视图不分包别的数据,因为大家尚未在数据库中增添多少(如图2-10)。
  • Entity Framework会利用Code
    First形式,基于大家的模型类成立BabyStore数据库。为了查看该数据库,在Visual
    Studio中开发SQL Server对象能源微型机。若是SQL
    Server对象财富微处理器未有现身,则从主菜单中式茶食击【视图】->【SQL
    Server对象财富微处理器】。

图2-14:富含产物数据的付加物目录(Index)页面

图2-18:依据字母顺序对分类名称进行排序

 1 using System.ComponentModel.DataAnnotations;
 2 
 3 namespace BabyStore.Models
 4 {
 5     public class Product
 6     {
 7         public int ID { get; set; }
 8         [Display(Name = "Product Name")]
 9         public string Name { get; set; }
10         public string Description { get; set; }
11         public decimal Price { get; set; }
12         public int? CategoryID { get; set; }
13         public virtual Category Category { get; set; }
14     }
15 }

澳门新葡亰平台官网 2

  在数据库中列出的每一种列都和模型类的属性相匹配。表名被暗许设置为复数情势。Categories表富含ID和Name列。Products表满含ID、Name、Description、Price列以至八个外键列CategoryID。每一种列的数据类型和模型类中的属性的数据类型相相配。

  值得注意的是,我们得以不在web.config文件中定义连接字符串,假若那样做的话,Entity
Framework将会采纳基于上下文类的暗许设置。

2.5.3.1
使用MetaDataType将数据评释分割为另三个文本

2.2 增多数据库上下文

  Delete方法也可以有八个版本。ASP.NET
MVC基架就要删除的详细消息体现给顾客,在顾客真正付诸删除必要从前行行确认。我们在此先列出GET版本的Delete方法,我们会小心到该措施和Details方法十一分等级次序,使用ID找到二个分拣,并将该分类数据传递给视图。

  点击每三个链接,未来都会张开附加物的目录(Index)页面,在该页面中只展现了与该分类有关的制品音讯。

 1 // GET: Categories/Delete/5
 2 public ActionResult Delete(int? id)
 3 {
 4     if (id == null)
 5     {
 6         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
 7     }
 8     Category category = db.Categories.Find(id);
 9     if (category == null)
10     {
11         return HttpNotFound();
12     }
13     return View(category);
14 }
 1 @model BabyStore.Models.Category
 2 
 3 @{
 4     ViewBag.Title = "Create";
 5 }
 6 
 7 <h2>Create</h2>
 8 
 9 @using (Html.BeginForm())
10 {
11     @Html.AntiForgeryToken()
12 
13     <div class="form-horizontal">
14         <h4>Category</h4>
15         <hr />
16         @Html.ValidationSummary(true, "", new { @class = "text-danger" })
17         <div class="form-group">
18             @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
19             <div class="col-md-10">
20                 @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
21                 @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
22             </div>
23         </div>
24 
25         <div class="form-group">
26             <div class="col-md-offset-2 col-md-10">
27                 <input type="submit" value="Create" class="btn btn-default" />
28             </div>
29         </div>
30     </div>
31 }
32 
33 <div>
34     @Html.ActionLink("Back to List", "Index")
35 </div>
36 
37 @section Scripts {
38     @Scripts.Render("~/bundles/jqueryval")
39 }

  注意:假诺你想安份守己本章的代码编写示例,你一定要做到第一章只怕直接从www.apress.com下载第一章的源代码。

  分类的编纂视图展现了叁个同意顾客编辑分类音讯的HTML表单,分类音讯由CategoriesController调节器类的Edit方法(GET版本)传递给该视图。那个视图非常临近于成立(Create)视图。该视图自动生成的代码如下所示:

 1 namespace BabyStore.Models
 2 {
 3     public class Product
 4     {
 5         public int ID { get; set; }
 6         public string Name { get; set; }
 7         public string Description { get; set; }
 8         public decimal Price { get; set; }
 9         public int? CategoryID { get; set; }
10         public virtual Category Category { get; set; }
11     }
12 }

2.4.2
检查CategoriesController类和章程

  以后,大家早就有了数据库上下文和一些模子类,今后要求大家告知Entity
Framework怎样连接到数据库。在Web.config文件的connectionString节点参与二个新的条规:

 1 // POST: Categories/Edit/5
 2 // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
 3 // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
 4 [HttpPost]
 5 [ValidateAntiForgeryToken]
 6 public ActionResult Edit([Bind(Include = "ID,Name")] Category category)
 7 {
 8     if (ModelState.IsValid)
 9     {
10         db.Entry(category).State = EntityState.Modified;
11         db.SaveChanges();
12         return RedirectToAction("Index");
13     }
14     return View(category);
15 }

  新加上的分类音讯已经被增多到数据库中,因为当客商点击分类的制造(Create)页面中的Create开关时,CategoriesController类中的Create方法(POST版本)被调用,然后将新分类音信保存到数据库中。

注意:在视图中自动生成的私下认可的表头和标签对于客商的选择不太对劲儿,因而小编在紧接着的截图中对他们举办了校订。假如大家想本身开展修正,能够仿效第二章的源码,该源码能够从www.Apress.com下载。笔者没有在本书中对代码实行改良,因为它们太过重复和麻烦。

  • 模型类:Product
  • 多少上下文类:StoreContext
  • 管教生成视图、引用脚本库和动用构造页选项被勾选上
  • 保留调节器名称设置为ProductsController(全体端详参见图2-8)

图2-17:产物目录(Index)页面展现的数目注解的显得名称

  这段代码应用HTML的ActionLink支持器方法生成叁个超链接,该链接的呈现文本是分类的称谓,指标是ProductsController的Index方法。第四个参数是路由参数,用于将分类的Name属性值赋值给category参数,该参数会跟随U翼虎L传递给指标措施参数。使用这种格局和大家利用手动格局的成效近似,都会在UENVISIONL的前边扩大category=caegoryname样式的参数。

 1 // GET: Categories/Details/5
 2 public ActionResult Details(int? id)
 3 {
 4     if (id == null)
 5     {
 6         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
 7     }
 8     Category category = db.Categories.Find(id);
 9     if (category == null)
10     {
11         return HttpNotFound();
12     }
13     return View(category);
14 }

  Details方法基于id参数从数据库查询有些分类音信,就像是大家在第1章见到的那么,系统选择路由系统将U昂科拉L中的id参数字传送递给该措施的id参数。

 1 using System.Collections.Generic;
 2 using System.ComponentModel.DataAnnotations;
 3 
 4 namespace BabyStore.Models
 5 {
 6     public class Category
 7     {
 8         public int ID { get; set; }
 9 
10         [Display(Name = "Category Name")]
11         public string Name { get; set; }
12         public virtual ICollection<Product> Products { get; set; }
13     }
14 }

  Inex方法用于重返全体分类的列表给ViewsCategoriesIndex.cshtml视图:

澳门新葡亰平台官网 3

  在缓慢解决方案能源微型机中,右键单击BabyStore项目,然后创建三个名称为“DAL”的公文夹。在该文件夹中开创二个名称为“StoreContext.cs”的类,然后在那类中增添如下代码:

  在此个视图中的各种条款如下所示:

  新搭建的CategoriesController.cs文件满含对分类奉行CRUD(新建、查询、更新和删除)操作的多少个章程。

2.4.4.1 检查付加物资调剂节器和视图

  • ID—主键。
  • Name—分类的名目。
  • Products—导航属性,该属性包蕴归于该分类的装有产品实业。

  products变量使用Where方法匹配付加物的归类名称与传递进入的category参数值一致的那多少个成品。那也是有一点大惊小怪,同期,大家或者也会吸引为何我们不应用CategoryID而是使用字符串来给Index方法传值。关键原因在于,当大家选拔路由时,使用分类名称越发有意义。我们将要本书后续章节呈报相关文化。

  在该视图中使用了与索引(Index)视图中一模一样的HTML帮忙器,但本次不须求使用循环,因为唯有三个纯净实体,如图2-4所示。

  Create方法的另二个本子接纳HTTP
POST伏乞。该措施在客户提交成立(Create)视图的表单时被调用。它含有一个Category类型的参数,并将该参数表示的Category对象增加到数据库中。若是该办法实行成功则赶回到目录(Index)视图,不然,它会再次加载创设(Create)视图。

2.4.3 检查分类视图

2.4.3.3
分类的成立(Create)视图

  修改后的代码所发生的结果将和图2-17体现的职能等同。然则,使用这种编码方法,除了将Product类表明为多个分局类之外,未有对Product类实行此外退换。当我们选取一些自动生成的类,而大家又不想对那几个类进行改正时,那是一种非凡实用的战术,比方,当大家利用Entity
Framework的DataBase First方式时。在本书中,大家一贯不蕴含Entity
Framework的Database
First相关知识,然而我们将陈述其余一种境况:对一个一度存在的数据库使用Code
First。

  Create方法的GET版本只是轻便地回到Create视图。第一遍见到这几个措施也许有一些不熟悉,它的含义是回去二个视图,在该视图中彰显三个空的HTML表单,用于创设叁个新的分类。

   未来大家供给加多一些调整器和视图来保管和显式我们的出品和分类数据。

  注意:保险使用的是项目根目录下的Web.config文件,而不是Views文件夹中的Web.config文件。

  这段代码澳元引(Index)视图轻便,它只显示单一实体。文件的第一行代码所钦点的模型是叁个单纯实体并非会晤。

  这段代码将一个条目款项赋值给了ViewBage的CategoryID属性。那一个条目款项是四个SelectList对象,该指标包蕴数据库中的全数分类,每三个条文使用Name属性作为要展现的公文,使用ID属性作为其值。可选的第几个参数决定在select列表中早期选定的条规。比如,假设第八个参数product.CategoryID设置为2,那么视图中的分类下拉列表大校会优先选定分类Toys。图2-9出示了它在视图中的样子。

 图2-1:运用Entity Framework创立调控器和视图

  @model BabyStore.Models.Category

  与分类有关的视图可在ViewsCategories文件夹中找到。每三个CRUD动作(详细情形、创造、编辑和删除卡塔尔皆有一个视图,索引(Index)视图用于浮现全部分类的叁个列表。

 1 // GET: Categories/Edit/5
 2 public ActionResult Edit(int? id)
 3 {
 4     if (id == null)
 5     {
 6         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
 7     }
 8     Category category = db.Categories.Find(id);
 9     if (category == null)
10     {
11         return HttpNotFound();
12     }
13     return View(category);
14 }

澳门新葡亰平台官网 4

ViewBag.CategoryID = new SelectList(db.Categories, “ID”, “Name”);

  点击【调节和测量试验】->【最早实施(不调节和测量试验State of Qatar】运维应用程序,然后点击分类链接。将来比物连类将会依据字母顺序对产物的名号实行排序,如图2-18所示。

  Edit方法的GET版本包蕴的代码和Details方法的代码相仿。该格局依据ID找到一个分拣,然后将该分类数据传递给视图。该视图按一定的格式展现分类音讯,并同意举办编辑。

 1 // POST: Categories/Create
 2 // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
 3 // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
 4 [HttpPost]
 5 [ValidateAntiForgeryToken]
 6 public ActionResult Create([Bind(Include = "ID,Name")] Category category)
 7 {
 8     if (ModelState.IsValid)
 9     {
10         db.Categories.Add(category);
11         db.SaveChanges();
12         return RedirectToAction("Index");
13     }
14 
15     return View(category);
16 }

  Edit方法的POST版本和Create方法的POST版本很周边。它含有一行额外的代码用于在将实体保存到数据库以前检查该实体是不是被涂改善,假使形式实施成功,则赶回到目录(Index)视图,不然重新显示编辑(Edit)视图。

4、点击“增多”按键,则会在Controllers文件夹中创制多个ProductsController类,与之相关的视图会创建在ViewsProducts文件夹中。

  大家不期待客商在浏览器地址栏中手动输入USportageL来导航到大家新建的视图,由此,大家需求改革主站点的导航栏:

澳门新葡亰平台官网 5

  要察看数据库中的新列,在SQL Server对象能源管理器中开展以下节点:SQL
Server>(localdbState of QatarMSSQLLocalDB>数据库>BabyStore>表>dbo.Categories>列。同期也将dbo.Products>列张开,如图2-11。

1 // GET: Categories/Create
2 public ActionResult Create()
3 {
4     return View();
5 }

图2-12:含有外键约束的Products表的设计器

  注意:对于刚(Yu-Gang卡塔尔(قطر‎刚起头使用Entity
Framework的编码职员来讲,最广大的失实是在错误之处使用了ToList(卡塔尔国方法。在二个办法中,LINQ日常用于创设二个询问,可是不进行这么些查询!查询只在ToList(卡塔尔(قطر‎方法被调用时才被实践。初级编码人士频频在他们方法的发端就选用ToList(卡塔尔(قطر‎方法,那常常引致相当多的记录(平时是有着的记录)从数据库中搜寻出来,在那之中多少记录并非所需求的,进而对质量发生影响。全数那个记录都被保存在内部存款和储蓄器中,并作为内部存款和储蓄器中的列表举行拍卖,那平日是不可取的,它会使站点的想能大幅下跌。作为选拔,大家依然都无须调用ToList(卡塔尔(قطر‎方法,当加载视图时,查询会被施行。这些话题被称呼延迟实行,延迟试行归功于查询独有在ToList(卡塔尔方法被调用时才会推行。

澳门新葡亰平台官网 6

澳门新葡亰平台官网 7

  CategoriesController包含下列格局。

  在本书中,大家从不详尽描述LINQ或lambda表达式。假诺您想对其询问的越多,我们提议您读下AndrewTroelsen编写的一本特别优异的书籍:Pro C#(中文图书名字为:掌握C#)。

  在类中运用数据注明能够使得大家的代码更易维护,因为对此属性名称的来得只需求在一个地点进行调整就能够。大家也足以在视图中期维改进显示名称,但这涉及到多少个文本,因而变得难以维护,其余,对于大家利用该属性创制的视图,以后都亟待被更新。

  为了缓慢解决那几个难题,大家能够应用一个誉为数据注脚的ASP.NET本性在分拣和付加物的模型类的Name属性上添加八个Display个性。

澳门新葡亰平台官网 8

  数据库创设完结之后,我们还学习了怎么样检查它以致哪些矫器重图以改进与基架相关的主题材料。从那开头,本章余下的局地首要描述了怎么样采用分类过滤产物,怎么着使用导航属性以至哪些从视图链接到分歧的动作方法。

  在connectionString节点中存在的别样条约是在我们创制工程时自动创立的,之所以会自行创制那几个数据库是因为大家在身份验证选项中筛选了“个人顾客账户”。大家将要本书的三番一遍章节切磋那么些难点。

澳门新葡亰平台官网 9

  为了演示新章程抵达的效用,大家运营站点,然后导航到产物的目录(Index)页面。今后我们在UENVISIONL后边最佳代码?category=clothes。将来,产品列表将会被相称的体系过滤,如图2-19。

  提示:要移除不无需的using语句,大家只需将光标悬停在using语句上,点击现身的古铜黑灯泡,然后选用“删除无需的using”选项就能够。

图5-16:付加物的目录(Index)页面中的多个Name表头

  自动生成的CategoriesViewsIndex.cshtml视图像和文字件如下所示:

图2-13:含有五个测量检验分类数据的分类索引(Index)页面

 1 using BabyStore.Models;
 2 using System.Data.Entity;
 3 
 4 namespace BabyStore.DAL
 5 {
 6     public class StoreContext : DbContext
 7     {
 8         public DbSet<Product> Products { get; set; }
 9         public DbSet<Category> Categories { get; set; }
10     }
11 }

  第一处退换是ProductsController的Index方法,如下所示:

  下边,大家在Models文件夹下再新建多少个名称为“Category”的模型类,然后在这类中增加如下代码:

1、右击Controllers文件夹,然后选拔【增加】->【调控器】。

 1 @model BabyStore.Models.Category
 2 
 3 @{
 4     ViewBag.Title = "Edit";
 5 }
 6 
 7 <h2>Edit</h2>
 8 
 9 @using (Html.BeginForm())
10 {
11     @Html.AntiForgeryToken()
12 
13     <div class="form-horizontal">
14         <h4>Category</h4>
15         <hr />
16         @Html.ValidationSummary(true, "", new { @class = "text-danger" })
17         @Html.HiddenFor(model => model.ID)
18 
19         <div class="form-group">
20             @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
21             <div class="col-md-10">
22                 @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
23                 @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
24             </div>
25         </div>
26 
27         <div class="form-group">
28             <div class="col-md-offset-2 col-md-10">
29                 <input type="submit" value="Save" class="btn btn-default" />
30             </div>
31         </div>
32     </div>
33 }
34 
35 <div>
36     @Html.ActionLink("Back to List", "Index")
37 </div>
38 
39 @section Scripts {
40     @Scripts.Render("~/bundles/jqueryval")
41 }

  要想进一层详实地翻看各样表的详细的情况,右击表,然后在菜单中接纳【视图设计器】。使用视图设计器,大家得以进一层详实地翻看表中的各样列,以致外键。在图2-1第22中学,我们能够看看Products表的安顿性以致T-SQL部分,T-SQL部分的第8行代码用于安装外键约束,表面该外键列援引Categories表中的ID列。

   在这里一章中,大家上学了怎么着成立模型类以致如何依照模型类生成数据库。大家还学习了何等钦赐数据库连接字符串,以至哪些成立数据库上下文。那几个类以至大家的模子类可用于创建调节器和视图,大家还创办和填充了数据库。

  在Models文件夹中加多一个名称为ProductMetaData.cs的公文,然后改过其代码如下所示:

图2-3:分类索引(Index)视图生成的HTML页面(包涵示例数据)

  Delete方法的POST版本施行四个防伪检查,它首先选取ID找到一个分拣,然后移除它,最终保存对数据库的改过。

图2-19:选用UWranglerL地址栏依据clothes分类过滤付加物

2.7
依照项目过滤付加物:使用导航属性和Include寻觅相关实业

澳门新葡亰平台官网 10

  通过上述的改动,分类的目录(Index)页面未来满含了链接到ProductsController的Index方法的超链接,如图2-20所示。

澳门新葡亰平台官网 11

  未来将Product类证明成了三个分局类,那表示将此类分割为了三个文件。数据评释[MetadataType(typeof(ProductMetaData))]用于告诉.NET要今后自于ProductMetaData类的元数据运用于Product类。

图2-6:分拣的编纂(艾德it)视图所生成的HTML页面,分类的当前名称被先行填充在输入框中。

  为了测验新视图的效益,我们点击分类的目录(Index)视图中的Create
New链接来增加一些数额。增加多少个分类:Clothes、Toys和Feeding。当大家做到这个操作后,分类的目录(Index)页面如图2-13所示。

图2-15:翻看数据库中的Products表数据

澳门新葡亰平台官网 12

图2-11:SQL
Server对象财富微型机中显示的最早的BabyStore数据库,分类和付加物表的列依次打开,并出示出各类列的数据类型

 1 @model BabyStore.Models.Category
 2 
 3 @{
 4     ViewBag.Title = "Details";
 5 }
 6 
 7 <h2>Details</h2>
 8 
 9 <div>
10     <h4>Category</h4>
11     <hr />
12     <dl class="dl-horizontal">
13         <dt>
14             @Html.DisplayNameFor(model => model.Name)
15         </dt>
16 
17         <dd>
18             @Html.DisplayFor(model => model.Name)
19         </dd>
20 
21     </dl>
22 </div>
23 <p>
24     @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
25     @Html.ActionLink("Back to List", "Index")
26 </p>

  移除文件上边全数无需的using语句。Category类包括的习性如下所示:

表2-1:增加到站点的制品消息

 1 // POST: Categories/Delete/5
 2 [HttpPost, ActionName("Delete")]
 3 [ValidateAntiForgeryToken]
 4 public ActionResult DeleteConfirmed(int id)
 5 {
 6     Category category = db.Categories.Find(id);
 7     db.Categories.Remove(category);
 8     db.SaveChanges();
 9     return RedirectToAction("Index");
10 }

  这是贰个非常好的事例,它显得了领航属性是老大实惠和强硬的。由于接受了Product类中的导航属性,大家得以使用比较少的代码来查找八个相关的实业。若是大家想依靠分类名称来协作成品,不过不利用导航属性的话,大家亟须在ProductsController中加载分类实体,不过遵照常规,ProductsController只对产物进行保管。

2.1 增加模型类

  实现那么些功用相当的轻松,张开ControllersCategoriesController.cs文件,然后将Index方法改过成如下代码:

图2-9:选取product.CategoryID参数在下拉列表中优先选定的成分值

  付加物的目录(Index)页面满含多少个名叫Name的标题,如图2-16所示。那是因为在视图中选拔了@Html.DisplayNameFor(model
=>
model.Category.NameState of Qatar代码来显示分类的Name属性,紧接着也选取了该办法来展示成品的Name属性。在付加物的实际情况(Details)页面也会有平等的标题,那引致了顾客接纳的吸引。

  在询问字符串中的任何参数都会活动相称指标措施的参数。由此,在此个事例中,U翼虎L中的?category=clothes相配ProductsController中的Index方法的category参数,当时,该参数的值为clothes。

  将Product类校勘成原来的事态,可是将它注脚为二个根据地类,以便与注解在ProductMetaData.cs文件中的Product类证明实行统一。

2、在“增加基架”窗体中,采用“包括视图的 MVC 5 调控器(使用 Entity
Framework卡塔尔”选项(如图2-1)。

图2-5:分拣的创制(Create)视图所生成的HTML页面,这一个页面包涵二个用来提交新分类音信的HTML表单

  • ID—用于表示产物(product)在数据库中的主键。
  • Name—产品(product)的名称。
  • Description—关于产物的文件描述。
  • Price—表示产品的价位。
  • CategoryID—表示钦点给产物(product)的分类(category)ID。在数据库中习感到常被安装为外键。大家还将该属性的花色设置为可空整型(int?),用于描述那样一个实际:有个别成品恐怕不归属别的分类。那可以幸免在对分类实践删除操作时,该分类下的持有付加物也被删除的景观爆发。暗中认可情形下,Entity
    Framework对可空类型外键启用级联删除,也正是说,假诺CategoryID不是可空的,当一个分类被删去时,全部与该分类相关联的制品也会被删除。
  • Category—导航属性。导航属性包罗与该实体相关的别的实体,在此种地方下,那特天性将含有该付加物所属的分类实体。假使三个导航数据足以包括四个实体,那么它必需被定义为汇集类型。平常使用ICollection类型。导航属性凉常被定义为virtual,以便能够不蔓不枝有个别特殊的成效,比如延迟加载。

  这段代码应用LINQ方法语法(method
syntax)来钦点对哪些列进行排序。lambda表明式用于钦赐要排序的列是Name列。这段代码将回到叁个排序过的分类列表给视图显示。LINQ表示Language-Integrated
Query,它是内置在.NET框架中的一个询问语言。使用LINQ方斯拉维尼亚语法(method
syntax)意味着所创办的询问能够使用点“.”急迅地将三个法子进行链接。五个可替换方阿拉伯语法(method
syntax)的主意是使用查询语法(query
syntax),大家就要第3章给出贰个编纂的一个比较复杂的询问例子。方瑞典语法(method
syntax)在外观上更像SQL的语法,对于比较复杂的查询能够让大家更便于明白。然则,对于稍短的查询它呈现就比较冗长。

   提示:大家能够在Visual
Studio中输入prop,然后按两遍Tab键来自动生成属性。

澳门新葡亰平台官网 13

  ProductsController调控器类和与之有关的视图和后边所陈说的CategoriesController类极度相同,大家就不再详细描述了。然则,该视图包括了三个非凡重大的新职能,应用程序必要提供一种格局关联系产能品和分类,在该视图中所采纳的诀固然利用select元素突显四个下拉列表,以便顾客在开立产物和编写制定成品时得以接收成品所对应的归类。

2.3 钦赐连接字符串

   Entity
Framework的代码优先情势允许大家从模型类创立数据库。我们将创建表示产品和分类的四个模型类来发轫本章的就学。我们还就要付加物和分类之内增添0或1对多的关联,表示两个出品得以归于四个分类或不归于别的分类,四个分拣能够包括多少个产物。

  • 修正ProductsController的Index方法,使它能够收到八个参数,该参数表示选择的归类,并且再次来到三个属于该分类的出品列表。
  • 将分类索引(Index)页中的文本列表改革成超链接列表,该超链接的对象是ProductsController的Index方法。

  代码private StoreContext db = new
StoreContext(卡塔尔国;伊始化了调整器要选取的三个上下文对象。该目的在调节器的满贯生命周期中都可应用,在调整器的Dispose方法被调用时释放。

  • 首先个新特征应用的代码是@Using(Html.BeginForm(卡塔尔State of Qatar,该代码行告诉视图将以此using语句中的全部代码都打包在HTML表单中。
  • @Html.AntiForgeryToken(State of Qatar生成叁个anti-forgery
    token,被相称的POST版本的Create方法用于检查(使用[ValidateAntiForgeryToken]特性)。
  • @Html.ValidationSummary(true, “”, new { @class = “text-danger”
    }卡塔尔(قطر‎是另一个援助器,用于呈现一个荒诞摘要(引致表单无效的任何原因)。第二个参数告诉摘要消弭别的性质错误,只呈现模型品级的不当,第四个参数new
    { @class = “text-danger” }用于采纳Bootstrap的text-danger
    CSS类样式化错误音信(那是三个革命的公文,越来越多关于Bootstrap和CSS的知识包括在本书后续章节)。
  • @Html.LabelFor(model => model.Name, htmlAttributes: new { @class
    = “control-label col-md-2” }卡塔尔国创制了八个新的HTML
    label成分,该label成分与随着的HTML输入控件(分类的Name属性)相关联。
  • @Html.EditorFor(model => model.Name, new { htmlAttributes = new {
    @class = “form-control” }
    }卡塔尔是另一个HTML协助器方法,能够依附钦定属性的多寡格式来展现精确的HTML输入成分。在这里个例子中,属性是Name,因而EditorFor方法尝试着体现准确的HTML成分类型以允许顾客编辑字符串。在这里个状态下,它在HTML表单中开创了一个文书框成分,所以客户能够输入分类的称谓。
  • 在这里个视图中的最终二个新HTML扶持器是@Html.ValidationMessageFor(model
    => model.Name, “”, new { @class = “text-danger”
    }State of Qatar。这段代码对质量加多了独特的证实音讯,假诺客商输入的属性值不合法了在程序中设置的印证法规,则会触发三个错误。当前,大家还尚未安装法则,但是大家就要第4章学习怎么设置它。
  • 在这里个视图中还可能有三个额外的片段是在目录(Index)视图和实际情况(Details)视图像和文字件中未有的,它用于包蕴验证所需的JavaScript文件(更加多知识点将要第4章陈述):

    1 @section Scripts {
    2 @Scripts.Render(“~/bundles/jqueryval”)
    3 }

 1 @model BabyStore.Models.Category
 2 
 3 @{
 4     ViewBag.Title = "Delete";
 5 }
 6 
 7 <h2>Delete</h2>
 8 
 9 <h3>Are you sure you want to delete this?</h3>
10 <div>
11     <h4>Category</h4>
12     <hr />
13     <dl class="dl-horizontal">
14         <dt>
15             @Html.DisplayNameFor(model => model.Name)
16         </dt>
17 
18         <dd>
19             @Html.DisplayFor(model => model.Name)
20         </dd>
21 
22     </dl>
23 
24     @using (Html.BeginForm())
25     {
26         @Html.AntiForgeryToken()
27 
28         <div class="form-actions no-color">
29             <input type="submit" value="Delete" class="btn btn-default" /> |
30             @Html.ActionLink("Back to List", "Index")
31         </div>
32     }
33 </div>

5、点击“加多”开关,则会在Controllers文件夹中开创多少个CategoriesController类,与之生死相依的视图会创制在ViewsCategories文件夹中。

  右击Models文件夹,然后从菜单中选择【加多】->【类】,创立三个名字为“Product”的新类,然后在这里类中增多如下代码:

图2-20:带有超链接的、用于过滤产物的分类索引(Index)页面。标红的有的是clothes链接生成的U福睿斯L。

 4、点击“添加”按键,然后在“增多调控器”窗口中选取下列选项:

   删除(Delete)视图和详细的情况(Details)视图很相同,并且也包含一个HTML表单,用于提交到CategoriesController调节器类的Delete方法(POST版本)。除了前方我们所检查的视图所包括的原委之外,该视图未有蕴含别的任何新的特点。自动生成的代码如下所示,该视图所生成的HTML如图2-7所示:

  点击成品链接,然后再点击Create
New链接来加多一些产物数量。增多的产品数量如表2-1所示。

  在Create方法的GET版本中,与之周围似的代码如下所示:

  lambda表明式是无名氏情势,那些艺术可用于创立委托。简单的话,lambda表明式能够让大家成立三个表明式,该表明式的lambda操作符(=>卡塔尔(قطر‎左侧的值是输入参数,右侧的是要计算的表明式和重临值。思虑地点我们输入的lambda表明式,它富含四个Category类型的输入参数,然后重返分类的Name属性。因而,总来讲之,它发挥的意味正是遵从分类的Name属性排序。

  这几个条目款项告诉Entity
Framework要延续的是项目App_Data文件夹中的BabyStore.mdf数据库。大家选择在此个文件夹中储存数据库是因为它能够跟随项目一道被复制。AttachDbFilename=|DataDirectory|BabyStore.mdf;指定在App_Data文件夹中开创数据库。

  为了将分类更正为超链接,大家修改ViewsCategoriesIndex.cshtml文件,将其文件中的@Html.DisplayFor(modelItem
=> item.Name卡塔尔国修正为:

  • 模型类:Category
  • 数码上下文类:StoreContext
  • 承保生成视图、援用脚本库和平运动用结构页选项被勾选上
  • 保存调整器名称设置为CategoriesController(全体端详参见图2-2)

  下边一行代码所展示的Include方法是三个运用预先加载(eager
loading)的例证:

  因为该方式是三个HTTP POST,它满含部分额外的代码:

澳门新葡亰平台官网 14

  由基架生成的ViewsCategoriesDetails.cshtml视图像和文字件如下所示:

  按相似的点子改进ModelsProduct.cs文件中的代码:

1 // GET: Categories
2 public ActionResult Index()
3 {
4     return View(db.Categories.ToList());
5 }

  一些开辟职员钟爱模型类尽或许地简单明了,因而,不情愿对模型类增添数据注明。这可以动用MetaDataType类来实现这种须求。

  在视图中显得HTML的select成分使用下列HTML帮忙器方法:@Html.DropDownList(“CategoryID”,
null, htmlAttributes: new { @class = “form-control” }State of Qatar。

  由于成品实业富含了贰个对分类实体的外键援引,自动生成的Delete方法不能够准确的办事。大家就要第4章学习怎样修改该难点。

澳门新葡亰平台官网 15

澳门新葡亰平台官网 16

  在调整器中,实现那几个效应的代码可以在Edit方法(GET版本和POST版本)和Create方法(POST版本)中找到:

澳门新葡亰平台官网 17

3、在“增添基架”窗体中,选拔“包涵视图的MVC 5 调控器(使用 Entity
Framework卡塔尔”选项,如图2-1所示。

  创造(Create)视图显示了二个空表单以允许大家创造一个分类。为了扭转一个HTML表单,该视图达成了一些在目录(Index)视图和实际情况(Details)视图中未有包含的新特点。这几个表单使用POST央求提交,该央浼会被POST版本的Create方法处理。这么些视图自动生成的代码如下所示:

澳门新葡亰平台官网 18
  每叁遍点击付加物的创始(Create)页面包车型大巴Create按键,ProductsController类的Create方法(POST版本)都会被调用,进而保留产物数量到数据库中。

  它告诉Entity
Framework去施行二个纯粹查询,检索出具备的出品和那一个产物有关的分类新闻。预先加载(eager
loading)会产生三个SQL连接查询,它二回搜索出所需的有所数据。大家得以忽视Include方法,这个时候,Entity
Framework将会接收延缓加载(lazy
loading),那将波及三个查询实际不是几个纯净的接二连三查询。

 1 @foreach (var item in Model)
 2 {
 3     <tr>
 4         <td>
 5             @*@Html.DisplayFor(modelItem => item.Name)*@
 6             @Html.ActionLink(item.Name, "Index", "Products", new { category = item.Name }, null)
 7         </td>
 8         <td>
 9             @Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
10             @Html.ActionLink("Details", "Details", new { id = item.ID }) |
11             @Html.ActionLink("Delete", "Delete", new { id = item.ID })
12         </td>
13     </tr>
14 }
  • @model
    IEnumerable<BabyStore.Models.Category>是该视图所依靠的模型。CategoriesController调整器类的Index方法向索引(Index)视图传递了叁个分拣列表。在此个事例中,视图必要向客商体现分类新闻列表,因而模型内定为贯彻了IEnumerable接口的分类集合。
  • 当前页的title属性使用下列代码举行了安装:

    1 @{
    2 ViewBag.Title = “Index”;
    3 }

  • @Html.ActionLink(“Create New”, “Create”State of Qatar创设了叁个文书为“Create
    New”的、链接到创设(Create)视图的超链接。那是多个利用HTML协理器的事例,ASP.NET
    MVC通过行使那几个协助器来渲染各类分歧的多少驱动的HTML成分。

  • @Html.DisplayNameFor(model =>
    model.Name卡塔尔国展现模型中内定属性的值。在此个例子中,它突显了分类的Name属性的的值。
  • 下一场代码循环遍历模型中带有的每叁个分类,并呈现每一种分类的Name属性所蕴藏的值,前面紧跟多个链接:Edit、Details和Delete(如图2-3)。ActionLink方法的首个参数用于向链接展开的视图提供分类的id。

    1 @foreach (var item in Model)
    2 {
    3

    4

    5 @Html.DisplayFor(modelItem => item.Name)
    6

    7

    8 @Html.ActionLink(“Edit”, “Edit”, new { id = item.ID }) |
    9 @Html.ActionLink(“Details”, “Details”, new { id = item.ID }) |
    10 @Html.ActionLink(“Delete”, “Delete”, new { id = item.ID })
    11

    12

    13 }

2.4.3.4 分类的编排(Edit)视图

 1 namespace BabyStore.Models
 2 {
 3     public partial class Product
 4     {
 5         public int ID { get; set; }
 6         public string Name { get; set; }
 7         public string Description { get; set; }
 8         public decimal Price { get; set; }
 9         public int? CategoryID { get; set; }
10         public virtual Category Category { get; set; }
11     }
12 }
 1 using System.ComponentModel.DataAnnotations;
 2 
 3 namespace BabyStore.Models
 4 {
 5     [MetadataType(typeof(ProductMetaData))]
 6     public partial class Product
 7     {
 8     }
 9 
10     public class ProductMetaData
11     {
12         [Display(Name = "Product Name")]
13         public string Name;
14     }
15 }

2.6
轻易询问:依据字母顺序对分类实行排序

2.4.3.1 分类的目录(Index)视图

2.4.1 增加分类调节器和视图

 1 @model IEnumerable<BabyStore.Models.Category>
 2 
 3 @{
 4     ViewBag.Title = "Index";
 5 }
 6 
 7 <h2>Index</h2>
 8 
 9 <p>
10     @Html.ActionLink("Create New", "Create")
11 </p>
12 <table class="table">
13     <tr>
14         <th>
15             @Html.DisplayNameFor(model => model.Name)
16         </th>
17         <th></th>
18     </tr>
19 
20     @foreach (var item in Model)
21     {
22         <tr>
23             <td>
24                 @Html.DisplayFor(modelItem => item.Name)
25             </td>
26             <td>
27                 @Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
28                 @Html.ActionLink("Details", "Details", new { id = item.ID }) |
29                 @Html.ActionLink("Delete", "Delete", new { id = item.ID })
30             </td>
31         </tr>
32     }
33 
34 </table>

澳门新葡亰平台官网 19

  这段代码给Index方法增多了二个名称叫category的字符串参数。if语句用于检查category参数是不是为空,要是该参数不为空,将会使用Product类的导航属性Category来对产品举办过滤,代码为:products
= products.Where(p => p.Category.Name == categoryState of Qatar;。

  Product类包蕴以下属性:

  译者注:现身说法数据的增进大家前面会讲到,那儿有一点提前。

 1 using System.Collections.Generic;
 2 
 3 namespace BabyStore.Models
 4 {
 5     public class Category
 6     {
 7         public int ID { get; set; }
 8         public string Name { get; set; }
 9         public virtual ICollection<Product> Products { get; set; }
10     }
11 }

澳门新葡亰平台官网 20

澳门新葡亰平台官网 21

  在此一章中,大家将一向进去项目,况且为成品和分类增添一些主导的模型类。大家就要Entity
Framework的代码优先进轨范式下,利用这几个模型类成立一个数据库。大家还将学习怎样在代码中创立数据库上下文类、钦定数据库连接字符串以至开创叁个数据库。最终,大家还将增加视图和调控器来治本和显式成品和分类数据。

2.8 小节

  [Display(Name = “Category
Name”)]告知MVC框架在体现属性名称标签的时候,不选择Name而是使用Category
Name。

1 // GET: Categories
2 public ActionResult Index()
3 {
4     return View(db.Categories.OrderBy(c => c.Name).ToList());
5 }

3、点击“增加”开关,然后在“加多调整器”窗口中甄选下列选项:

1、打开ViewsShared_Layout.cshtml文件。

2.5.2 使用视图增添一些数目

2.4.4 加多产物资调剂节器和视图

1 <connectionStrings>
2     <add name="DefaultConnection" connectionString="Data Source=(LocalDb)MSSQLLocalDB;AttachDbFilename=|DataDirectory|aspnet-BabyStore-20161229112118.mdf;Initial Catalog=aspnet-BabyStore-20161229112118;Integrated Security=True"
3       providerName="System.Data.SqlClient" />
4     <add name="StoreContext" connectionString="Data Source=(LocalDB)MSSQLLocalDB;AttachDbFilename=|DataDirectory|BabyStore.mdf;Initial Catalog=BabyStore;Integrated Security=True"
5       providerName="System.Data.SqlClient" />
6   </connectionStrings>
 1 <div class="navbar-collapse collapse">
 2     <ul class="nav navbar-nav">
 3         <li>@Html.ActionLink("主页", "Index", "Home")</li>
 4         <li>@Html.ActionLink("关于", "About", "Home")</li>
 5         <li>@Html.ActionLink("联系方式", "Contact", "Home")</li>
 6         <li>@Html.ActionLink("分类", "Index", "Categories")</li>
 7         <li>@Html.ActionLink("产品", "Index", "Products")</li>
 8     </ul>
 9     @Html.Partial("_LoginPartial")
10 </div>

图2-2:增添新分类调整器的取舍

2.5.3
使用数据申明的法子改良分类和产物的Name属性的浮现

ViewBag.CategoryID = new SelectList(db.Categories, “ID”, “Name”,
product.CategoryID);

2.5.1
检查新创建的BabyStore数据库

2.4.3.5
分类的删减(Delete)视图

  上下文类世襲自System.Data.Entity.DbContext类,常常情状下,三个数据库对应三个数据库上下文类,在某个相比较复杂的类型中恐怕对应两个。每二个DbSet类型的习性被称得上实体集,平常对应数据库中的某三个表,比方Products属性对应数据库中的Products表。代码DbSet<Product>告诉Entity
Framework使用Product类来代表Products表中的一行数据。

  注意:有多少个原因引致ASP.NET采用了不容许GET央浼更新数据库的诀窍,也会有超级多有关那样做的安全性的评论和纠纷。不过,那样做的最关键的由来是搜索引擎爬行器会爬行大家站点中的全数公开的超链接,假若那几个链接中带有未证实就能够删除记录的链接,那么,也许会促成数据库中的相关数据被去除。稍后我们会给编写制定分类增多安全机制,由此,那将形成三个有争辨的主题材料。

  对于数据模型来讲,数据库上下文是和煦Entity Framework功用最要害的类。

  在ModelsCategory.cs文件中增添如下高亮显示的代码:

  在文件的上面移除全部不供给的using语句。

图2-4:分拣详细(Details)视图生成的HTML页面

1 var products = db.Products.Include(p => p.Category);

  图2-6显得了所生成的编辑撰写页面。在这里个视图中并世无双的叁个新的HTML支持器方法是@Html.HiddenFor(model
=>
model.ID卡塔尔国。该语句创造了叁个带有分类ID的藏匿的HTML输入成分,用于CategoriesController调控器类的Edit方法(POST版本)的Bind成分:public
ActionResult Edit([Bind(Include = “ID,Name”)] Category category)。

图2-8:增加新付加物资调剂控器的选项

  二个可选的钦定连接字符串的条规是Data
Source=(LocalDBState of QatarMSSQLLocalDB;Initial Catalog=BabyStore.mdf;Integrated
Security=True,它钦点在客户文件夹(日常在Windows系统中是C:UsersUser)中开创数据库。

  这段代码基于ViewBag.CategoryID属性生成贰个HTML成分,并将该因素的CSS
class属性设置为form-control。在DropDownList扶助器方法中,若是第一个字符串参数的值相称ViewBag属性的名字,它将会自动使用那么些值,而不会再内定多个到ViewBag的援用。

2、在代码<li>@Html.ActionLink(“联系形式”, “Contact”,
“Home”卡塔尔</li>的底下增加分类和产品的目录(Index)页面:

3、点击【调试】->【初步施行(不调节和测量试验State of Qatar】,Web站点将会运转。点击“分类”链接的时候将会爆发两件事:

1、从Visual
Studio菜单中,点击【生成】->【生成施工方案】来生成解决方案。

  选用选取那一种加载方法有一对性质上的差别。预先加载对数据库进行二遍询问就足以获取结果,可是,假若利用相比较复杂的总是语句会产生品质裁减。延迟加载会对数据库进行频繁查询技能获得所需数据。在这个时候,大家采纳预先加载是因为老是语句比较容易,同时,大家必要加载相关的分类音信以便对齐实行检索。

  在分拣的目录(Index)视图中所彰显的归类近年来是比照ID来开展排序的,我们能够改良成依据字母逐条对分类的称号进行排序。

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图