9.3.10  设计StoreManagerController控制器

9.3.10 设计StoreManagerController控制器

1.添加StoreManageController控制器

同添加StoreController控制器一样,添加StoreManageController控制器。在类的第一行定义一个MusicStoreEntities类的实例storeDB,代码如下:

978-7-111-46863-9-Chapter09-87.jpg

2.修改Index方法并创建index视图

Index视图获取专辑的列表,包含每一个专辑引用的流派和艺术家信息,向在前面Store控制器的Browse时候看到的,Index视图中需要包含对于链接到的流派和艺术家对象来显示相关的信息,所以,在Index的Action方法中,需要包含这些数据。然后单击“index”方法创建一个强类型的视图,代码如下:

978-7-111-46863-9-Chapter09-88.jpg

3.修改Details方法

在Details方法中,类似于Store控制器的Details方法,通过专辑的Id来获取专辑对象,这里使用Find()方法完成,最后,把这个对象传递给视图,代码如下:

978-7-111-46863-9-Chapter09-89.jpg

4.创建Create方法

与前面看到的不同,Create方法需要处理表单,当用户第一次访问地址/StoreManager/Create的时候,用户将会看到一个空的表单,HTML页面中包含一个<form>元素,其中包含了下拉列表和文本框等输入元素,用户可以借助它们输入专辑的详细信息。

当用户填写了专辑的信息之后,可以通过单击“保存”按钮来提交表单信息到服务器,应用程序可以获取这些信息保存到数据库中。在用户单击“保存”的时候,浏览器发出一个Http的Post请求,到/StoreManager/Create地址,表单的内容作为这个Post请求的一部分发送回服务器。

ASP.NET MVC可以容易地分割这两种同样对于Create方法的请求处理,通过提供两个同名的Create方法,一个用来处理Http Get请求,一个用来处理Http Post请求,区分的方式是在处理Post请求的方法前面增加一个[HttpPost]的标签。如果增加[HttpGet]标签,则表示这个方法仅仅处理Http Get请求。通常没有这个标签,则表示无论是Get请求还是Post请求都可以由这个Action方法处理。修改Greate方法代码如下:

978-7-111-46863-9-Chapter09-90.jpg

978-7-111-46863-9-Chapter09-91.jpg

注意:ViewBag是信息传递的一种方法。它允许向视图传递信息而不需要首先定义强类型的Model,在创建专辑的过程中,在表单中需要两个列表框,便于选择专辑所属流派和专辑的艺术家,使用viewbag来传递这两个信息最好不过了。

ViewBag是动态对象,这意味着可以使用ViewBag.Foo或者ViewBag.YourNameHere形式的属性而不需要预先定义这些属性,控制器中的代码使用ViewBag.GenreId和View- Bag.Artisid传递流派和艺术家的信息以便生成表单中下拉列表的值。

传递到视图的下拉列表的值使用SelectList对象表示,代码如下:

978-7-111-46863-9-Chapter09-92.jpg

该方法中的3个参数被用于创建这个对象:

第一个参数用来生成下拉列表中信息的集合,这里是流派对象的集合。

第二个参数提供下拉列表中的值,这是一个字符串,实际上是流派对象的一个属性GenreId。

最后的参数提供下拉列表中显示出来的值,这里使用流派的Name属性。后两个参数的名称必须包含在第一个对象的属性集合中。

5.添加Create视图

选择“create”action,右击选择“添加视图”,在随后弹出的如图9-42所示的添加视图对话框中,选择视图引擎为“Razor”,勾选“创建强类型视图”,选择模型类为album,选择支架模板为“create”,单击“添加”按钮完成视图创建工作。

978-7-111-46863-9-Chapter09-93.jpg

图9-42 添加Create强类型视图

打开views/StoreManage/create.cshtml文件,找到唱片流派编辑框,将@Html.EditFor(model=>model.GenreId)修改为@Html.DropDownList("GenreId",String.Empty)。将@Html.EditFor(model=>model.ArtistId)修 改 为@Html.DropDownList("ArtistId",String.Empty)。

注意:Html.DropDownList方法需要两个参数,从哪里获取显示用的列表,和哪一个值需要被预先选中,方法的第一个参数,GenreId,告诉DropDownList从模型对象或者ViewBag对象中寻找名为GenreId的属性值,第二个参数用来指出下拉列表默认选中的值。这是创建专辑的表单,所以,没有需要预先选中的值,这里传递了一个String.Empty。

6.创建Create方法获取post表单值

前面讨论过,对于一个表单可以有两个对应的处理方法,一个处理Http Get请求显示表单,另外一个用于处理Http Post请求,用于处理提交的表单数据,注意,在控制器中,处理Http Post请求的方法需要通过标签[HttpPost]进行标注,这样,这个方法将会被ASP.NET仅仅用来处理Post请求。代码如下:

978-7-111-46863-9-Chapter09-94.jpg

这个Action方法完成4个任务:①读取表单的数据。②检查表单的数据是否通过了验证规则。③如果表单通过了验证,保存数据,然后显示更新之后的专辑列表。④如果表单没有通过验证,重新显示带有验证提示信息的表单,如图9-43所示。

注意:Create()方法的参数是Album,而不是FormCollection类型。控制器处理的表单提交中包含了流派的标识GenreId和艺术家标识ArtistId,这些来自下拉列表框,以及通过文本框输入的Title,Price等数据,虽然可以直接通过FormCollection来访问表单数据,但是,更好的做法是使用ASP.NET MVC内置提供的模型绑定。因为当Action方法的参数是模型类型的时候,ASP.NET MVC将会试图使用表单中的数据来填充对象的属性,它通过检查表单参数的名字是否匹配模型对象的属性来进行,例如,对于专辑对象的GenreId属性来说,它将会在表单数据中查找名为GenreId的值赋予它。当使用标准的模型方式生成视图的时候,表单会使用模型对象的属性名称来生成表单输入项目的名称,这样,在发出表单的时候,请求参数就会正好匹配模型的属性了。

978-7-111-46863-9-Chapter09-95.jpg

图9-43 添加专辑

7.修改Edit方法

在Edit的Get方法中,使用唱片的Id来加载原有的唱片,这个参数通过路由传递过来,实际的代码类似在Details中看到的处理。除了专辑对象,同时还有处理下拉列表,所以,这里也通过ViewBag来处理,这样就允许在传递一个Model的同时还通过ViewBag传递了两个额外的SelectList。代码如下:

978-7-111-46863-9-Chapter09-96.jpg

然后,选择Edit方法,右击“添加视图”,创建一个强类型的视图文件edit.cshtml。然后修改流派和艺术家两栏为下拉选择框类型。@Html.DropDownList("GenreId",String.Empty)、@Html.DropDownList("ArtistId",String.Empty)。运行效果如图9-44所示。

处理Post请求的Edit方法也非常类似于Create的Post处理方法,仅有的不同就是不用创建一个新的专辑对象加入到集合中,而是将现有的专辑对象,注意已经通过模型绑定获取了请求参数,将这个对象的状态属性State修改为Modified,这就会告诉EF正在修改一个存在的专辑对象,而不是创建一个新的。代码如下:

978-7-111-46863-9-Chapter09-97.jpg

978-7-111-46863-9-Chapter09-98.jpg

图9-44 编辑专辑

下面运行程序测试一下,浏览/StoreManager,然后单击Edit链接即可以修改专辑的信息,如图9-45所示。单击Save,回到专辑列表,可以看到专辑信息已经被更新,如图9-46所示。

8.处理删除方法

删除的处理模式与Edit和Create一样,使用控制器的一个删除action显示确认信息,使用另外一个Action来处理提交。

删除的Get处理非常类似于前面的Details处理,代码如下:

978-7-111-46863-9-Chapter09-99.jpg

978-7-111-46863-9-Chapter09-100.jpg

图9-45 修改专辑信息

978-7-111-46863-9-Chapter09-101.jpg

图9-46 更新后的专辑信息

右击“delete”方法,添加视图,在如图9-47所示打开的“添加视图”对话框中,视图名称不变,勾选“构建强类型视图”,选择“支架模板”为delete,勾选“使用布局或母版页”,单击“添加”按钮完成视图的创建。

随后打开delete.cshtml文件,默认的Delete视图使用模型来显示所有对象信息,但是,这里仅仅需要简单地显示确认信息就可以。下列代码即是把这个视图修改一下,只保留确认信息。

978-7-111-46863-9-Chapter09-102.jpg

978-7-111-46863-9-Chapter09-103.jpg

978-7-111-46863-9-Chapter09-104.jpg

图9-47 添加删除视图

确认页面运行效果如图9-48所示。

978-7-111-46863-9-Chapter09-105.jpg

图9-48 确认删除专辑

单击Delete按钮之后,将导致表单发送到服务器,在此重定义了Delete方法,方法名为DeleteConfirmed,之所以修改方法名,是因为同一个方法名,如果参数相同,则不能同时出现。而且如果使用别名,则必须用[HttpPost,ActionName("Delete")]说明DeleteCon- firmed方法是Delete的Action处理方法。下面代码是确认删除的处理代码,注意,方法的参数只有专辑id。代码如下:

978-7-111-46863-9-Chapter09-106.jpg

运行程序,选择一个专辑,然后删除它,如图9-49~图9-51所示。

978-7-111-46863-9-Chapter09-107.jpg

图9-48 删除前专辑列表

978-7-111-46863-9-Chapter09-108.jpg

图9-50 删除确认

978-7-111-46863-9-Chapter09-109.jpg

图9-51 删除后专辑列表