ASP.NET MVC 3 Helpers, Forms And Validation

Total Page:16

File Type:pdf, Size:1020Kb

ASP.NET MVC 3 Helpers, Forms And Validation

1.

Hands-On Lab ASP.NET MVC Helpers, Forms and Validation

2. Lab version: 1.1.0 3. Last updated: 11/28/2017

4.

Page 1 CONTENTS 5.

Page 2 Overview

6. Note: This Hands-on Lab assumes you have basic knowledge of ASP.NET MVC. If you have not used ASP.NET MVC before, we recommend you to go over ASP.NET MVC Fundamentals Hand- on Lab.

7. 8. In ASP.NET MVC Models and Data Access Hand-on Lab, you have been loading and displaying data from the database. In this Hands-on Lab, you will add to the Music Store application the ability to edit that data. 9. With that goal in mind, you will first create the controller that will support the Create, Read, Update and Delete (CRUD) actions of albums. You will generate an Index View template taking advantage of ASP.NET MVC’s scaffolding feature to display the albums’ properties in an HTML table. To enhance that view, you will add a custom HTML helper that will truncate long descriptions. 10. Afterwards, you will add the Edit and Create Views that will let you alter the albums in the database, with the help of form elements like dropdowns. 11. Lastly, you will let users delete an album and also you will prevent them from entering wrong data by validating their input.

Objectives 1. In this Hands-On Lab, you will learn how to: Create a controller to support CRUD operations Generate an Index View to display entity properties in an HTML table Add a custom HTML helper Create and customize an Edit View Differentiate between action methods that react to either HTTP-GET or HTTP-POST calls Add and customize a Create View Handle the deletion of an entity Validate user input

Page 3 System Requirements 1. You must have the following items to complete this lab: ASP.NET and ASP.NET MVC 3 Visual Studio 2010 Express SQL Server Database (Express edition or above)

1.a. Note: You can install the previous system requirements by using the Web Platform Installer 3.0: http://go.microsoft.com/fwlink/?LinkID=194638.

Setup

Installing Code Snippets 1. For convenience, much of the code you will be managing along this lab is available as Visual Studio code snippets. To install the code snippets run .\Source\Assets\CodeSnippets.vsi file.

Exercises 1. This Hands-On Lab is comprised by the following exercises: 2. Exercise 1: Creating the Store Manager controller and its Index view 3. Exercise 2: Adding an HTML Helper 4. Exercise 3: Creating the Edit View 5. Exercise 4: Adding a Create View 6. Exercise 5: Handling Deletion 7. Exercise 6: Adding Validation

1. Estimated time to complete this lab: 35 minutes.

2. Note: Each exercise is accompanied by an End folder containing the resulting solution you should obtain after completing the exercises. You can use this solution as a guide if you need additional help working through the exercises.

3.

Page 4 Next Step Exercise 1: Creating the Store Manager controller and its Index view

Exercise 1: Creating the Store Manager controller and its Index view

1. In this exercise, you will learn how to create a new controller to support CRUD operations, customize its Index action method to return a list of albums from the database and finally generating an Index View template taking advantage of ASP.NET MVC’s scaffolding feature to display the albums’ properties in an HTML table. Task 1 – Creating the StoreManagerController 2. In this task, you will create a new controller called StoreManagerController to support CRUD operations. 3. Start Microsoft Visual Web Developer 2010 Express from Start | All Programs | Microsoft Visual Studio 2010 Express | Microsoft Visual Web Developer 2010 Express. 4. In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex01- CreatingTheStoreManagerController\Begin, select MvcMusicStore.sln and click Open. 5. Add the new controller. To do this, right-click the Controllers folder within the Solution Explorer, select Add and then the Controller command. Change the Controller Name to StoreManagerController and make sure that the checkbox Add action methods for Create, Update, Delete, and Details scenarios is checked. Click Add.

5.a. 5.b. Figure 1 5.c. Add Controller Dialog

5.d.

Page 5 6. A new Controller class is generated. Since you indicated to add action methods for Create, Update, Delete, and Details scenarios, stub methods for those, common CRUD actions are created with TODO comments filled in, prompting to include the application specific logic. 7. Since you don’t need the Details Controller action, delete that method.

Task 2 – Customizing the StoreManager Index 1. In this task, you will customize the StoreManager Index action method to return a View with the list of albums from the database. 2. If you are using C#, add a using directive to MvcMusicStore.Models: 2.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex1 using MvcMusicStore – CSharp) 2.b. C# 2.c. using System.Web.Mvc; 2.d. using MvcMusicStore.Models;

3. Add a field to the StoreManagerController to hold an instance of MusicStoreEntities. 3.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex1 MusicStoreEntities – CSharp) 3.b. C# 3.c. public class StoreManagerController : Controller 3.d. { 3.e. MusicStoreEntities storeDB = new MusicStoreEntities();

3.f. 3.g. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex1 MusicStoreEntities – VB) 3.h. Visual Basic 3.i. Public Class StoreManagerController

3.j. Inherits System.Web.Mvc.Controller 3.k.

3.l. Dim storeDB As New MusicStoreEntities

4. Implement the StoreManagerController Index action to return a View with the list of albums. The Controller action logic will be very similar to the StoreController’s Index action written earlier. Use LINQ to retrieve all albums, including Genre and Artist information for display.

Page 6 (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex1 StoreManagerController Index – CSharp) 4.a. C# 4.b. // 4.c. // GET: /StoreManager/ 4.d. 4.e. public ActionResult Index() 4.f. { 4.g. var albums = storeDB.Albums 4.h. .Include("Genre").Include("Artist") 4.i. .ToList(); 4.j. 4.k. return View(albums); 4.l. }

4.m. 4.n. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex1 StoreManagerController Index – VB) 4.o. Visual Basic 4.p. ' 4.q. 'GET: /StoreManager 4.r. 4.s. Function Index() As ActionResult

4.t. Dim albums = storeDB.Albums.Include("Genre").Include("Artist").ToList() 4.u.

4.v. Return View(albums) 4.w. End Function

4.x.

Task 3 – Creating the Index View 1. In this task, you will create the Index View template to display the list of albums returned by the StoreManager Controller.

Page 7 2. Before creating the new View template, you should build the project so that the Add View Dialog knows about the Album class to use. Build the project by selecting the Debug menu item and then Build MvcMusicStore.

2.a. 2.b. Figure 2 2.c. Building the project

2.d. 3. Right-click inside the Index action method and select Add View. This will bring up the Add View dialog.

3.a. 3.b. Figure 3 3.c. Adding a View from within the Index method

3.d. 4. In the Add View dialog, verify that the View Name is Index. Check the Create a strongly- typed view checkbox and select Album (MvcMusicStore.Models) from the View data class drop-down. Select List from the View content drop-down. Leave the View Engine to ASPX (C#| VB) and the other fields with their default value and then click Add.

Page 8 4.a. 4.b. Figure 4 4.c. Adding an Index View

4.d.

Task 4 – Customizing the scaffold of the Index View 1. In this task, you will adjust the simple View template created with ASP.NET MVC scaffolding feature to have it display the fields you want.

2. Note: The scaffolding support within ASP.NET MVC generates a simple View template which lists all fields in the Album model. Scaffolding provides a quick way to get started on a strongly typed view: rather than having to write the View template manually, scaffolding quickly generates a default template and then you can modify the generated code.

3. 4. Review the code created. The generated list of fields will be part of the following HTML table that Scaffolding is using for displaying tabular data. 4.a. HTML(C#) 4.b.

Page 9 4.c.

4.d.

4.e.

4.h.

4.k.

4.n.

4.q.

4.t.

4.u. 4.v. <% foreach (var item in Model) { %>

4.w.

4.x.

4.ac.

4.af.

4.ai.

4.al.

4.ao.

4.ar.

4.as. <% } %>

4.at. 4.au.

4.f. GenreId

4.g.

4.i. ArtistId

4.j.

4.l. Title

4.m.

4.o. Price

4.p.

4.r. AlbumArtUrl

4.s.

4.y. <%: Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) %> |

4.z. <%: Html.ActionLink("Details", "Details", new { id=item.AlbumId }) %> |

4.aa. <%: Html.ActionLink("Delete", "Delete", new { id=item.AlbumId }) %>

4.ab.

4.ad. <%: item.GenreId %>

4.ae.

Page 10 4.ag. <%: item.ArtistId %>

4.ah.

4.aj. <%: item.Title %>

4.ak.

4.am. <%: String.Format("{0:F}", item.Price) %>

4.an.

4.ap. <%: item.AlbumArtUrl %>

4.aq.

4.av. 4.aw. HTML(Visual Basic) 4.ax.

4.ay.

4.az.

4.ba.

4.bd.

4.bg.

4.bj.

Page 11 4.bm.

4.bp.

4.bq. 4.br. <% For Each item In Model %>

4.bs.

4.bt.

4.by.

4.cb.

4.ce.

4.ch.

4.ck.

4.cn.

4.co. <% Next %>

4.cp.

Page 12 4.cq.

4.bb. GenreId

4.bc.

4.be. ArtistId

4.bf.

4.bh. Title

4.bi.

4.bk. Price

4.bl.

4.bn. AlbumArtUrl

4.bo.

4.bu. <%: Html.ActionLink("Edit", "Edit", new with { id=item.AlbumId }) %> |

4.bv. <%: Html.ActionLink("Details", "Details", new with { id=item.AlbumId }) %> |

4.bw. <%: Html.ActionLink("Delete", "Delete", new with { id=item.AlbumId }) %>

4.bx.

4.bz. <%: item.GenreId %>

4.ca.

4.cc. <%: item.ArtistId %>

4.cd.

4.cf. <%: item.Title %>

4.cg.

4.ci. <%: String.Format("{0:F}", item.Price) %>

4.cj.

4.cl. <%: item.AlbumArtUrl %>

4.cm.

4.cr.

4.cs. Note: the generated template is following the same coding practices you have seen at ASP.NET MVC Fundamentals Hands-on lab: <%: %> code nuggets to HTML encode values, and Html.ActionLink() helper method to generate links to other controller actions.

4.ct. 5. Display only the Album Title, Artist, and Genre fields. To do this, delete the AlbumId, Price and Album Art URL columns. Also, change GenreId and ArtistId columns to display their linked class properties of Artist.Name and Genre.Name. Finally, remove the Details link. 5.a. To do this, replace the

code with the following: 5.b. HTML(C#) 5.c.
5.d. 5.e. 5.f. 5.g. 5.h. 5.i. 5.j. <% foreach (var item in Model) { %> 5.k. 5.l. 5.p. 5.q. 5.r. 5.s. 5.t. <% } %> 5.u.
TitleArtistGenre
5.m. <%: Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) %> | 5.n. <%: Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })%> 5.o. <%: item.Title %><%: item.Artist.Name %><%: item.Genre.Name %>

5.v. 5.w. HTML(Visual Basic)

Page 13 5.x.

5.y. 5.z. 5.aa. 5.ab. 5.ac. 5.ad. 5.ae. <% For Each item In Model %> 5.af. 5.ag. 5.ak. 5.al. 5.am. 5.an. 5.ao. <% Next %> 5.ap.
TitleArtistGenre
5.ah. <%: Html.ActionLink("Edit", "Edit", new with { id=item.AlbumId }) %> | 5.ai. <%: Html.ActionLink("Delete", "Delete", new with { id=item.AlbumId })%> 5.aj. <%: item.Title %><%: item.Artist.Name %><%: item.Genre.Name %>

5.aq. 6. Change the following descriptions. 6.a. HTML 6.b.

6.c. Store Manager - All Albums 6.d.

6.e. 6.f.

6.g.

6.h.

Albums

6.i.

Page 14 7. Also update the link to create a new Album changing its text. 7.a. HTML 7.b.

7.c. Store Manager - All Albums 7.d.

7.e. 7.f.

7.g.

7.h.

Albums

7.i.

7.j.

7.k. <%: Html.ActionLink("Create New Album", "Create") %>

7.l.

7.m.

Task 5 – Running the Application In this task, you will test that the StoreManager Index View template displays a list of albums according to the design of the previous steps. 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager to verify that a list of albums is displayed, showing their Title, Artist and Genre.

Page 15 2.a.

2.b. Figure 5 2.c. Browsing the list of Albums

2.d.

Next Step 1. Exercise 2: Adding an HTML Helper

1.

Page 16 Exercise 2: Adding an HTML Helper

2. The StoreManager Index page has one potential issue: Title and Artist Name properties can both be long enough to throw off the table formatting. In this exercise you will learn how to add a custom HTML helper to truncate that text. 3. In the following figure, you can see how the format is modified because of the length of the text.

4.

5. Figure 6 6. Browsing the list of Albums with not truncated text

7. Task 1 – Extending the HTML Helper 8. In this task, you will add a new method Truncate to the Html object exposed within ASP.NET MVC Views. To do this, you will implement an extension method to the built-in System.Web.Mvc.HtmlHelper class provided by ASP.NET MVC.

9. Note: To read more about extension methods, please visit this msdn article.

Page 17 10. Start Microsoft Visual Web Developer 2010 Express from Start | All Programs | Microsoft Visual Studio 2010 Express | Microsoft Visual Web Developer 2010 Express. 11. In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex02- AddingAnHTMLHelper\Begin, select MvcMusicStore.sln and click Open. 12. Add a new directory Helpers to place the new extension method. To do this, in the Solution Explorer, right-click the MvcMusicStore project, then Add, and New Folder.

12.a.

12.b. Figure 7 12.c. Adding Helpers folder

12.d. 13. Rename the folder to Helpers.

Page 18 13.a. 13.b. Figure 8 13.c. Helpers folder

13.d. 14. Add a new class HtmlHelpers in the Helpers folder. To do this, right-click the Helpers folder, select Add and then Class. In the Add New Item dialog, change the name to HtmlHelpers.[cs| vb] and click Add.

Page 19 14.a.

14.b. Figure 9 14.c. Adding the Album class – C#

14.d.

Page 20 14.e.

14.f. Figure 10 14.g. Adding HtmlHelpers class - VB

14.h. 15. Add a using directive to System.Web.Mvc and a new method to the class. Because of extension methods definition, HtmlHelpers and the new method need to be static. Replace with the following code: 15.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex2 TruncateMethod – CSharp) 15.b. C# 15.c. using System; 15.d. using System.Collections.Generic; 15.e. using System.Linq; 15.f. using System.Web;

15.g. 15.h. using System.Web.Mvc;

15.i.

Page 21 15.j. namespace MvcMusicStore.Helpers 15.k. {

15.l. public static class HtmlHelpers

15.m. {

15.n. public static string Truncate(this HtmlHelper helper, string input, int length)

15.o. {

15.p. if (input.Length <= length)

15.q. {

15.r. return input;

15.s. }

15.t. else

15.u. {

15.v. return input.Substring(0, length) + "...";

15.w. }

15.x. }

15.y. } 15.z. }

15.aa. 15.ab. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex2 TruncateMethod – VB) 15.ac. Visual Basic 15.ad. Public Module HtmlHelpers

15.ae.

15.af. Public Function Truncate(ByVal helper As HtmlHelper,

15.ag. ByVal input As String,

15.ah. ByVal length As Integer

15.ai.

15.aj. ) As String

15.ak.

15.al. If input.Length <= length Then

15.am. Return input

15.an. Else

Page 22 15.ao. Return input.Substring(0, length) & "..."

15.ap. End If

15.aq. End Function 15.ar. End Module

15.as. Note: This Truncate method will truncate a text if it is longer than the length parameter, adding a … for the remainder. If the text is shorter, the text will remain as is. 15.at. You may notice that the first parameter in the Truncate method includes a this. This is the way of defining the method as an extension method to the HtmlHelpers class. This will allow all HtmlHelpers class instances to use the Truncate method as if it was a class method. For example the implementation you will see in Task 3: Html.Truncate(item.Title, 25).

15.au.

Task 2 – Registering the HTML Helper 1. In this task, you will register the HTML Helper with the application by modifying the application’s Web.config file. 2. Open the Web.config file from the Solution Explorer. 3. Add a reference to the MvcMusicStore.Helpers namespace in the pages section. 3.a. XML(C#) 3.b.

3.c.

3.d.

3.e.

3.f.

3.g.

3.h.

3.i.

3.j. 3.k. XML(Visual Basic) 3.l.

3.m.

Page 23 3.n.

3.o.

3.p.

3.q.

3.r.

3.s.

3.t.

3.u. Note: Another aproach would be to add an import directive in all the pages that need it: 3.v. C# 3.w. <%@ Import Namespace="MvcMusicStore.Helpers" %>. 3.x. Visual Basic 3.y. <%@ Import Namespace="MvcMusicStore " %>. 3.z. Although, by adding the reference in the Web.config file, it will be available for all pages.

3.aa. 3.ab. You will find more information about import directive in this msdn article.

3.ac.

Task 3 – Truncating Text in the Page 1. In this task, you will use the Truncate method to truncate the text in the View template. 2. Open StoreManager’s Index View. To do this, in the Solution Explorer expand the Views folder, then the StoreManager and open the Index.aspx file. 3. Replace the lines that show the Album’s Title and Artist Name. To do this, replace the following lines: 3.a. HTML(C#) 3.b. <% foreach (var item in Model) { %>

3.c.

3.d.

3.e.

Page 24 3.f. <%: Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) %> |

3.g. <%: Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })%>

3.h.

3.i. <%: Html.Truncate(item.Title, 25) %>

3.j. <%: Html.Truncate(item.Artist.Name, 25) %>

3.k. <%: item.Genre.Name %>

3.l.

3.m. 3.n. <% } %>

3.o. 3.p. HTML(Visual Basic) 3.q. <% For Each item In Model %>

3.r.

3.s.

3.t.

3.u. <%: Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) %> |

3.v. <%: Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })%>

3.w.

3.x. <%: Html.Truncate(item.Title, 25) %>

3.y. <%: Html.Truncate(item.Artist.Name, 25) %>

3.z. <%: item.Genre.Name %>

3.aa.

3.ab. 3.ac. <% Next %>

3.ad.

Task 4 – Running the Application In this task, you will test that the StoreManager Index View template truncates the Album’s Title and Artist Name. 1. Press F5 to run the Application.

Page 25 2. The project starts in the Home page. Change the URL to /StoreManager to verify that long texts in the Title and Artist column are truncated.

2.a.

2.b. Figure 11 2.c. Truncated Titles and Artist Names

2.d.

Next Step 1. Exercise 3: Creating the Edit View

Exercise 3: Creating the Edit View

In this exercise, you will learn how to create a form to allow store managers to edit an Album. They will browse the /StoreManager/Edit/id URL (id being the unique id of the album to edit), thus making an HTTP-GET call to the server. The Controller Edit action method will retrieve the appropriate Album from the database, create a StoreManagerViewModel object to encapsulate it (along with a list of Artists and Genres), and then

Page 26 pass it off to a View template to render the HTML page back to the user. This page will contain a

element with textboxes and dropdowns for editing the Album properties. Once the user updates the Album form values and clicks the Save button, the changes are submitted via an HTTP-POST call back to /StoreManager/Edit/id. Although the URL remains the same as in the last call, ASP.NET MVC identifies that this time it is an HTTP-POST and therefore executes a different Edit action method (one decorated with [HttpPost]).

Task 1 – Creating the StoreManagerViewModel In order to build and manage the intended Edit form, you will first need to pass to the View template an object with the following: 1. An Album object that represents the current Album being edited 2. A List of all Genres to populate the Genre dropdown list 3. A List of all Artists to populate the Artist dropdown list

In this task, you will create a new StoreManagerViewModel class to help manage all of the above data. This class will be used within both Edit and Create action methods. 1. Start Microsoft Visual Web Developer 2010 Express from Start | All Programs | Microsoft Visual Studio 2010 Express | Microsoft Visual Web Developer 2010 Express. 2. In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex03- CreatingTheEditView\Begin, select MvcMusicStore.sln and click Open. 3. Create the StoreManagerViewModel class. To do this, right-click on the ViewModels folder, select Add and then Class. 4. Change the name to StoreManagerViewModel.[cs|vb] and click Add.

Page 27 4.a.

4.b. Figure 12 4.c. Creating StoreManagerViewModel class – C#

4.d.

Page 28 4.e.

4.f. Figure 13 4.g. Creating StoreManagerViewModel class - VB

4.h. 5. If you are using C#, add the following using directives: 5.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex3 using System.Web.Mvc and MvcMusicStore.Models – CSharp) 5.b. C# 5.c. using System; 5.d. using System.Collections.Generic; 5.e. using System.Linq; 5.f. using System.Web; 5.g. using System.Web.Mvc; 5.h. using MvcMusicStore.Models; 5.i. 6. Add the Album, Artists and Genres properties.

Page 29 6.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex3 StoreManagerViewModel properties– CSharp) 6.b. C# 6.c. public class StoreManagerViewModel

6.d. {

6.e. public Album Album { get; set; }

6.f. public SelectList Artists { get; set; }

6.g. public SelectList Genres { get; set; }

6.h. }

6.i. 6.j. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex3 StoreManagerViewModel properties– VB) 6.k. Visual Basic 6.l. Public Class StoreManagerViewModel

6.m.

6.n. Public Property Album As Album

6.o. Public Property Artists As SelectList

6.p. Public Property Genres As SelectList

6.q. 6.r. End Class

6.s.

6.t. Note: You are using System.Web.Mvc SelectList for Artists and Genres instead of the System.Collections.Generic List. 6.u. SelectList is a cleaner way to populate HTML dropdowns and manage things like current selection. Instantiating and later setting up these ViewModel objects in the controller action will make the Edit form scenario cleaner.

6.v.

Task 2 – Implementing the HTTP-GET Edit Action Method In this task, you will implement the HTTP-GET version of the Edit action method to retrieve the appropriate Album from the database, as well as a list of all Genres and Artists. It will package this data up into the StoreManagerViewModel object defined in the last step, which will then be passed to a View template to render the response with.

Page 30 1. Open StoreManagerController class. To do this, expand the Controllers folder and double- click StoreManagerController.[cs|vb]. 2. If you are using C#, add a using directive to MvcMusicStore.ViewModels. In order for the code to compile correctly, add the following using directive: 2.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex3 using MvcMusicStore.ViewModels – CSharp) 2.b. C# 2.c. using MvcMusicStore.Models; 2.d. using MvcMusicStore.ViewModels;

2.e. 3. Replace the HTTP-GET Edit action method with the following code to retrieve the appropriate Album as well as the Genres and Artists lists. 3.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex3 StoreManagerController HTTP-GET Edit action – CSharp) 3.b. C# 3.c. //

3.d. // GET: /StoreManager/Edit/5

3.e.

3.f. public ActionResult Edit(int id)

3.g. {

3.h. Album album = storeDB.Albums.Single(a => a.AlbumId == id);

3.i.

3.j. var viewModel = new StoreManagerViewModel()

3.k. {

3.l. Album = album,

3.m. Genres = new SelectList(storeDB.Genres.ToList(), "GenreId", "Name", album.GenreId),

3.n. Artists = new SelectList(storeDB.Artists.ToList(), "ArtistId", "Name", album.ArtistId)

3.o. };

3.p.

3.q. return View(viewModel);

3.r. }

3.s.

Page 31 3.t. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex3 StoreManagerController HTTP-GET Edit action – VB) 3.u. Visual Basic 3.v. '

3.w. 'GET: /StoreManager/Edit/5

3.x.

3.y. Function Edit(ByVal id As Integer) As ActionResult

3.z. Dim album As Album = storeDB.Albums.Single(Function(a) a.AlbumId = id)

3.aa.

3.ab. Dim viewModel = New StoreManagerViewModel With

3.ac. {.Album = album,

3.ad. .Genres = New SelectList(storeDB.Genres.ToList(), "GenreId", "Name", album.GenreId),

3.ae. .Artists = New SelectList(storeDB.Artists.ToList(), "ArtistId", "Name", album.ArtistId)}

3.af. Return View(viewModel)

3.ag. End Function

Task 3 – Creating the Edit View In this task, you will create an Edit View template that will later display the album properties. 1. Before creating the new View template, you should build the project so that the Add View Dialog knows about the class to use. Build the project by selecting the Debug menu item and then Build MvcMusicStore.

Page 32 1.a. 1.b. Figure 14 1.c. Building the project

1.d. 2. Create the Edit View. To do this, right-click inside the Edit action method and select Add View. 3. In the Add View dialog, verify that the View Name is Edit. Check the Create a strongly-typed view checkbox and select StoreManagerViewModel (MvcMusicStore.ViewModels) from the View data class drop-down. Select Edit from the View content drop-down. Leave the other fields with their default value and then click Add.

Page 33 3.a. 3.b. Figure 15 3.c. Adding an Edit View

3.d. 4. The generated Edit View template doesn’t include any fields because none of the properties in the StoreManagerViewModel are simple types like strings and integers.

4.a. 4.b. Figure 16

Page 34 4.c. Edit View without fields – C#

4.d.

4.e. 4.f. Figure 17 4.g. Edit View without fields - VB

4.h.

Task 4 – Customizing the Edit View 1. In this task, you will change the default View template to display the Album properties. 2. Add an Html.EditorFor() helper to render a default HTML editing form for the Album. 2.a. HTML(C#) 2.b. Edit Album

2.c.

2.d. <%: Html.EditorFor(model => model.Album,

2.e. new { Artists = Model.Artists, Genres = Model.Genres })%>

2.f.

2.g.

2.h.

2.i.

2.j. 2.k. HTML(Visual Basic) 2.l. Edit Album

2.m.

2.n. <%: Html.EditorFor(Function(model) model.Album,

Page 35 2.o. New With {Key .Artists = Model.Artists, Key .Genres = Model.Genres })%>

2.p.

2.q.

2.r.

2.s.

2.t.

2.u. Note: Html.EditorFor() helper will create a form that will enable the edition of its first parameter, in this case an Album. Additionally, you are passing a second parameter which is optional, that contains the list of Artists and Genres. This will be used later on.

2.v.

Task 5 – Running the Application In this task, you will test that the StoreManager Edit View page displays the properties’ values for the album passed as parameter. 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager/Edit/388 to verify that the properties’ values for the album passed are displayed.

Page 36 2.a.

2.b. Figure 18 2.c. Browsing Album’s Edit view

2.d.

Task 6 – Creating a Shared Album Editor Template Since the exact same form fields for Album Edit will be needed to handle the Album Create case, in this task you will create a Shared Album Editor template that will take care of both cases with the same code. 1. Close the browser if needed, to return to the Visual Studio window. Create a folder inside /Views/Shared folder and name it EditorTemplates.

Page 37 1.a.

1.b. Figure 19 1.c. Adding a new folder

1.d. 2. Right-click the EditorTemplates folder, select Add and then View.

2.a.

2.b. Figure 20 2.c. Adding a View template

2.d. 3. This will be a Partial View, meaning that it is intended to be displayed inside another view. In the Add View dialog, change the Name to Album. Check the Create a partial view (.ascx) checkbox and the Create a strongly-typed view checkbox. Select Album (MvcMusicStore. Models) from the View data class drop-down and select Edit from the View content drop- down. Leave the other fields with their default value and then click Add.

Page 38 3.a. 3.b. Figure 21 3.c. Adding a Partial View

3.d.

Task 7 – Implementing drop-downs on the Album Editor Template In this task, you will add drop-downs to the View template created in the last task, so that the user can select from a list of Artists and Genres. 1. Replace Album.ascx Partial View code with the following: 1.a. HTML(C#) 1.b. <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

1.c. 1.d.

1.e. <%: Html.LabelFor(model => model.Title) %>

1.f. <%: Html.TextBoxFor(model => model.Title) %>

1.g. <%: Html.ValidationMessageFor(model => model.Title) %>

Page 39 1.h.

1.i.

1.j. <%: Html.LabelFor(model => model.Price) %>

1.k. <%: Html.TextBoxFor(model => model.Price) %>

1.l. <%: Html.ValidationMessageFor(model => model.Price) %> 1.m.

1.n.

1.o. <%: Html.LabelFor(model => model.AlbumArtUrl) %>

1.p. <%: Html.TextBoxFor(model => model.AlbumArtUrl) %>

1.q. <%: Html.ValidationMessageFor(model => model.AlbumArtUrl) %> 1.r.

1.s.

1.t. <%: Html.LabelFor(model => model.Artist) %>

1.u. <%: Html.DropDownList("ArtistId", (SelectList) ViewData["Artists"]) %> 1.v.

1.w.

1.x. <%: Html.LabelFor(model => model.Genre) %>

1.y. <%: Html.DropDownList("GenreId", (SelectList) ViewData["Genres"]) %> 1.z.

1.aa. 1.ab. HTML(Visual Basic) 1.ac. <%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" 1.ad. Inherits="System.Web.Mvc.ViewPage(Of MvcMusicStore.Album)" %>

1.ae. 1.af.

1.ag. <%:Html.LabelFor(Function(model) model.Title)%>

1.ah. <%:Html.TextBoxFor(Function(model) model.Title)%>

1.ai. <%:Html.ValidationMessageFor(Function(model) model.Title)%> 1.aj.

1.ak.

1.al. <%:Html.LabelFor(Function(model) model.Price)%>

Page 40 1.am. <%:Html.TextBoxFor(Function(model) model.Price)%>

1.an. <%:Html.ValidationMessageFor(Function(model) model.Price)%> 1.ao.

1.ap.

1.aq. <%:Html.LabelFor(Function(model) model.AlbumArtUrl)%>

1.ar. <%:Html.TextBoxFor(Function(model) model.AlbumArtUrl)%>

1.as. <%:Html.ValidationMessageFor(Function(model) model.AlbumArtUrl)%> 1.at.

1.au.

1.av. <%:Html.LabelFor(Function(model) model.Artist)%>

1.aw. <%:Html.DropDownList("ArtistId", CType(ViewData("Artists"), SelectList))%> 1.ax.

1.ay.

1.az. <%:Html.LabelFor(Function(model) model.Genre)%>

1.ba. <%:Html.DropDownList("GenreId", CType(ViewData("Genres"), SelectList))%> 1.bb.

1.bc. Note: An Html.DropDownList helper has been added to render drop-downs for choosing Artists and Genres. The parameters passed to Html.DropDownList are: 1.bd. 1. The name of the form field (“ArtistId”) 1.be. 2. The SelectList of values for the drop-down. ViewData is actually the object taken from the Html.EditorFor second parameter you included in task 4: 1.bf. C# 1.bg. <%: Html.EditorFor(model => model.Album,

1.bh. new { Artists = Model.Artists, Genres = Model.Genres })%> Visual Basic <%:Html.EditorFor(Function(model) model.Album,

New With {Key .Artists = Model.Artists, Key .Genres = Model.Genres})%>

Page 41 1.bi. Html.EditorFor() helper will create a form that will enable the edition of its first parameter, in this case an Album. Additionally, you are passing a second parameter which is optional, that contains the list of Artists and Genres. This will be used later on.

1.bj.

Task 8 – Running the Application In this task, you will test that the StoreManager Edit View page displays drop-downs instead of Artist and Genre ID text fields. 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager/Edit/388 to verify that it displays drop-downs instead of Artist and Genre ID text fields.

2.a.

2.b. Figure 22 2.c. Browsing Album’s Edit view, this time with dropdowns

2.d.

Page 42 Task 9 – Implementing the HTTP-POST Edit action method 1. Now that the Edit View displays as expected, you need to implement the HTTP-POST Edit Action method to save the changes made to the Album. 2. Close the browser if needed, to return to the Visual Studio window. Open StoreManagerController from the Controllers folder. 3. Replace HTTP-POST Edit action method code with the following (note that the method that must be replaced is overloaded version that receives two parameters): 3.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex3 StoreManagerController HTTP-POST Edit action – CSharp) 3.b. C# 3.c. //

3.d. // POST: /StoreManager/Edit/5

3.e.

3.f. [HttpPost]

3.g. public ActionResult Edit(int id, FormCollection collection)

3.h. {

3.i. var album = storeDB.Albums.Single(a => a.AlbumId == id);

3.j.

3.k. try

3.l. {

3.m. // Save Album

3.n.

3.o. UpdateModel(album, "Album");

3.p. storeDB.SaveChanges();

3.q.

3.r. return RedirectToAction("Index");

3.s. }

3.t. catch

3.u. {

3.v. // Error occurred - so redisplay the form

3.w.

3.x. var viewModel = new StoreManagerViewModel()

3.y. {

Page 43 3.z. Album = album,

3.aa. Genres = new SelectList(storeDB.Genres.ToList(), "GenreId", "Name", album.GenreId),

3.ab. Artists = new SelectList(storeDB.Artists.ToList(), "ArtistId", "Name", album.ArtistId)

3.ac. };

3.ad.

3.ae. return View(viewModel);

3.af. }

}

3.ag. 3.ah. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex3 StoreManagerController HTTP-POST Edit action – VB) 3.ai. Visual Basic '

'POST: /StoreManager/Edit/5

Function Edit(ByVal id As Integer,

ByVal collection As FormCollection

) As ActionResult

3.aj. Dim album = storeDB.Albums.Single(Function(a) a.AlbumId = id)

3.ak.

3.al. Try

3.am. 'Save Album

3.an.

3.ao. UpdateModel(album, "Album")

3.ap. storeDB.SaveChanges()

3.aq.

3.ar. Return RedirectToAction("Index")

3.as. Catch

3.at. 'Error occurred - so redisplay the form

Page 44 3.au.

3.av. Dim viewModel = New StoreManagerViewModel With

3.aw. {.Album = album,

3.ax. .Genres = New SelectList(storeDB.Genres.ToList(), "GenreId", "Name", album.GenreId),

3.ay. .Artists = New SelectList(storeDB.Artists.ToList(), "ArtistId", "Name", album.ArtistId)}

3.az.

3.ba. Return View(viewModel)

3.bb. End Try

End Function

3.bc. Note: This method will be executed when the user clicks the Save button of the View and performs an HTTP-POST of the form values back to the server to persist them in the database. The decorator [HttpPost] indicates that the method should be used for those HTTP-POST scenarios. 3.bd. The method takes an id (read from the route parameter values) and a FormCollection (read from the HTML Form).

3.be. 3.bf. The method will perform three steps: 3.bg. 1. Load the existing album object from the database with the id passed as parameter 2. Try to update the album using the values posted from the client, using the Controller’s built-in UpdateModel method. The UpdateModel method actually relies on the ModelBinder (MVC 2.0) to identify that you are actually updating a StoreManagerViewModel instance. Since that ViewModel holds an Album object and also 2 SelectLists for Artists and Genres, the key “Album” you are including as UpdateModel’s second parameter, refers to the need of updating the “Album” property of the Model. 3.bh. 3. Display results back to the user – either by redisplaying the form in case of an error, or by redirecting back to the list of albums in case of a successful update

3.bi.

Task 10 – Running the Application In this task, you will test that the StoreManager Edit View page actually saves the updated Album data in the database.

Page 45 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager/Edit/388. Change the Album title to Greatest Hits Vol. 1 and click on Save. Verify that album’s title actually changed in the list of albums.

Page 46 2.a.

Page 47 2.b. Figure 23 2.c. Updating an Album

2.d.

Next Step 1. Exercise 4: Adding a Create View

Exercise 4: Adding a Create View

1. Now that the StoreManagerController supports the Edit ability, in this exercise you will learn how to add a Create View template to let store managers to add new Albums to the application. 2. Like you did with the Edit functionality, you will implement the Create scenario using two separate methods within the StoreManagerController class: 3. One action method will display an empty form when store managers first visit the /StoreManager/Create URL. 4. A second action method will handle the scenario where the store manager clicks the Save button within the form and submits the values back to the /StoreManager/Create URL as an HTTP-POST.

Task 1 – Implementing the HTTP-GET Create action method 1. In this task, you will implement the HTTP-GET version of the Create action method to retrieve a list of all Genres and Artists, package this data up into a StoreManagerViewModel object, which will then be passed to a View template. 2. Start Microsoft Visual Web Developer 2010 Express from Start | All Programs | Microsoft Visual Studio 2010 Express | Microsoft Visual Web Developer 2010 Express. 3. In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex04- AddingACreateView\Begin, select MvcMusicStore.sln and click Open. 4. Open StoreManagerController class. To do this, expand the Controllers folder and double- click StoreManagerController.[cs|vb]. 5. Replace the Create action method code with the following: 5.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex4 StoreManagerController HTTP-GET Create action – CSharp) 5.b. C#

Page 48 5.c. //

5.d. // GET: /StoreManager/Create

5.e.

5.f. public ActionResult Create()

5.g. {

5.h. var viewModel = new StoreManagerViewModel()

5.i. {

5.j. Album = new Album(),

5.k. Genres = new SelectList(storeDB.Genres.ToList(), "GenreId", "Name"),

5.l. Artists = new SelectList(storeDB.Artists.ToList(), "ArtistId", "Name")

5.m.

5.n. };

5.o.

5.p. return View(viewModel);

5.q. }

5.r. 5.s. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex4 StoreManagerController HTTP-GET Create action – VB) 5.t. Visual Basic 5.u. '

5.v. 'GET: /StoreManager/Create

5.w.

5.x. Function Create() As ActionResult

5.y.

5.z. Dim viewModel = New StoreManagerViewModel With

5.aa. {.Album = New Album,

5.ab. .Genres = New SelectList(storeDB.Genres.ToList(), "GenreId", "Name"),

5.ac. .Artists = New SelectList(storeDB.Artists.ToList(), "ArtistId", "Name")}

5.ad. Return View(viewModel)

Page 49 5.ae.

5.af. End Function

Task 2 – Adding the Create View 1. In this task, you will add the Create View template that will display a new (empty) Album form. 2. Before creating the new View template, you should build the project so that the Add View Dialog knows about the class to use. Build the project by selecting the Debug menu item and then Build MvcMusicStore.

2.a. 2.b. Figure 24 2.c. Building the project

2.d. 3. Right-click inside the Create action method and select Add View. This will bring up the Add View dialog. 4. In the Add View dialog, verify that the View Name is Create. Check the Create a strongly- typed view checkbox and select StoreManagerViewModel (MvcMusicStore.ViewModels) from the View data class drop-down. Select Create from the View content drop-down. Leave the other fields with their default value and then click Add.

Page 50 4.a. 4.b. Figure 25 4.c. Adding an Edit View

4.d. 5. Update the generated View template to invoke the Html.EditorFor() helper method: 5.a. HTML(C#) 5.b.

5.c. <% using (Html.BeginForm()) {%>

5.d. <%: Html.ValidationSummary(true) %>

5.e.

5.f.

5.g. Create Album

5.h. <%: Html.EditorFor(model => model.Album,

5.i. new { Artists = Model.Artists, Genres = Model.Genres })%>

5.j.

Page 51 5.k.

5.l.

5.m.

5.n.

5.o. <% } %>

5.p. 5.q. HTML(Visual Basic) 5.r. 5.s. <% Using Html.BeginForm() %>

5.t. <%: Html.ValidationSummary(True) %>

5.u.

5.v.

5.w. Create Album

5.x. <%: Html.EditorFor(Function(model) model.Album,

5.y. New With {Key .Artists = Model.Artists, Key .Genres = Model.Genres})%>

5.z.

5.aa.

5.ab.

5.ac.

5.ad. 5.ae. <% End Using %>

Task 3 – Running the Application In this task, you will test that the StoreManager Create View page displays an empty Album form. 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager/Create. Verify that an empty form is displayed for filling the new Album properties.

Page 52 2.a.

2.b. Figure 26 2.c. Create View with an empty form

2.d.

Task 4 – Implementing the HTTP-POST Create Action Method 1. In this task, you will implement the HTTP-POST version of the Create action method that will be invoked when a user clicks the Save button. The method should save the new album in the database. 2. Close the browser if needed, to return to the Visual Studio window. Open StoreManagerController class. To do this, expand the Controllers folder and double-click StoreManagerController.[cs|vb]. 3. Replace HTTP-POST Create action method code with the following: 3.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex4 StoreManagerController HTTP- POST Create action – CSharp) 3.b. C# 3.c. //

Page 53 3.d. // POST: /StoreManager/Create

3.e.

3.f. [HttpPost]

3.g. public ActionResult Create(Album album)

3.h. {

3.i. try

3.j. {

3.k. if (ModelState.IsValid)

3.l. {

3.m. // Save Album

3.n. storeDB.AddToAlbums(album);

3.o. storeDB.SaveChanges();

3.p.

3.q. return Redirect("Index");

3.r. }

3.s. }

3.t. catch (Exception ex)

3.u. {

3.v. ModelState.AddModelError(String.Empty, ex);

3.w. }

3.x.

3.y. // Invalid - redisplay with errors

3.z.

3.aa. var viewModel = new StoreManagerViewModel()

3.ab. {

3.ac. Album = album,

3.ad. Genres = new SelectList(storeDB.Genres.ToList(), "GenreId", "Name", album.GenreId),

3.ae. Artists = new SelectList(storeDB.Artists.ToList(), "ArtistId", "Name", album.ArtistId)

3.af. };

3.ag.

3.ah. return View(viewModel);

Page 54 3.ai. }

3.aj. 3.ak. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex4 StoreManagerController HTTP- POST Create action – VB) 3.al. Visual Basic 3.am. '

3.an. 'POST: /StoreManager/Create

3.ao.

3.ap.

3.aq. Public Function Create(ByVal album As Album) As ActionResult

3.ar. Try

3.as. If ModelState.IsValid Then

3.at. 'Save Album

3.au. storeDB.AddToAlbums(album)

3.av. storeDB.SaveChanges()

3.aw.

3.ax. Return Redirect("Index")

3.ay. End If

3.az. Catch ex As Exception

3.ba. ModelState.AddModelError(String.Empty, ex)

3.bb. End Try

3.bc.

3.bd. 'Invalid - redisplay with errors

3.be.

3.bf. Dim viewModel = New StoreManagerViewModel With

3.bg. {.Album = album,

3.bh. .Genres = New SelectList(storeDB.Genres.ToList(), "GenreId", "Name", album.GenreId),

3.bi. .Artists = New SelectList(storeDB.Artists.ToList(), "ArtistId", "Name", album.ArtistId)}

3.bj.

3.bk. Return View(viewModel)

3.bl. End Function

Page 55 Note: One difference from the previous Edit action method is that instead of loading an existing Album and calling UpdateModel, the action method is receiving an Album as a parameter. ASP.NET MVC will automatically create this Album object from the posted values. The method checks that the submitted values are valid, and if they are, it saves the new Album in the database and then redirects to the StoreManager Index View.

3.bm.

Task 5 – Running the Application In this task, you will test that the StoreManager Create View page lets you create a new Album and then redirects to the StoreManager Index View. 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager/Create. Fill the empty form with data for a new Album, like the one in the following figure:

2.a.

2.b. Figure 27

Page 56 2.c. Creating an Album

2.d. 3. Verify that you get redirected to the StoreManager Index View that includes the new Album just created.

3.a.

3.b. Figure 28 3.c. New Album created

3.d.

Next Step 1. Exercise 5: Handling Deletion

Exercise 5: Handling Deletion

Page 57 1. The ability to delete albums is not yet implemented. This is what this exercise will be about. Like before, you will implement the Delete scenario using two separate methods within the StoreManagerController class: 2. One action method will display a confirmation form 3. A second action method will handle the form submission

Task 1 – Implementing the HTTP-GET Delete Action Method 1. In this task, you will implement the HTTP-GET version of the Delete action method to retrieve the album’s information. 2. Start Microsoft Visual Web Developer 2010 Express from Start | All Programs | Microsoft Visual Studio 2010 Express | Microsoft Visual Web Developer 2010 Express. 3. In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex05- HandlingDeletion\Begin, select MvcMusicStore.sln and click Open. 4. Open StoreManagerController class. To do this, expand the Controllers folder and double- click StoreManagerController.[cs|vb]. 5. The Delete controller action is exactly the same as the previous Store Details controller action: it queries the album object from the database using the id provided in the URL and returns the appropiate View. To do this, replace the HTTP-GET Delete action method code with the following: 5.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex5 Handling Deletion HTTP-GET Delete action – CSharp) 5.b. C# 5.c. // 5.d. // GET: /StoreManager/Delete/5

5.e. 5.f. public ActionResult Delete(int id) 5.g. {

5.h. var album = storeDB.Albums.Single(a => a.AlbumId == id);

5.i.

5.j. return View(album); 5.k. }

5.l. 5.m. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex5 Handling Deletion HTTP-GET Delete action – VB)

Page 58 5.n. Visual Basic 5.o. ' 5.p. 'GET: /StoreManager/Delete/5

5.q. 5.r. Function Delete(ByVal id As Integer) As ActionResult

5.s. Dim album = storeDB.Albums.Single(Function(a) a.AlbumId = id)

5.t.

5.u. Return View(album) 5.v. End Function

6. Before creating the new View template, you should build the project so that the Add View Dialog knows about the class to use. Build the project by selecting the Debug menu item and then Build MvcMusicStore.

6.a. 6.b. Figure 29 6.c. Building the project

6.d. 7. Right-click inside the Delete action method and select Add View. This will bring up the Add View dialog. 8. In the Add View dialog, verify that the View name is Delete. Check the Create a strongly- typed view checkbox and select Album (MvcMusicStore.Models) from the View data class drop-down. Select Delete from the View content drop-down. Leave the other fields with their default value and then click Add.

Page 59 8.a. 8.b. Figure 30 8.c. Adding a Delete View

8.d. 9. The Delete template shows all the fields from the model. You will show only the album’s title. To do this, replace the asp:Content with the following code: 9.a. HTML(C#) 9.b.

9.c.

9.d.

Delete Confirmation

9.e.

9.f.

9.g. Are you sure you want to delete the album titles

9.h. <%: Model.Title %> ?

9.i.

9.j.

Page 60 9.k.

9.l. <% using (Html.BeginForm()) { %>

9.m. |

9.n. <%: Html.ActionLink("Back to List", "Index") %>

9.o. <% } %>

9.p.

9.q. 9.r.

9.s. 9.t. HTML(Visual Basic) 9.u.

9.v.

9.w.

Delete Confirmation

9.x.

9.y.

9.z. Are you sure you want to delete the album titles

9.aa. <%: Model.Title %> ?

9.ab.

9.ac.

9.ad.

9.ae. <% using Html.BeginForm()%>

9.af. |

9.ag. <%: Html.ActionLink("Back to List", "Index") %>

9.ah. <% End Using %>

9.ai.

9.aj. 9.ak.

9.al.

Task 2 – Running the Application In this task, you will test that the StoreManager Delete View page displays a confirmation deletion form.

Page 61 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager. Select one album to delete by clicking Delete and verify that the new view is uploaded.

2.a.

2.b. Figure 31 2.c. Deleting an Album

2.d.

Task 3– Implementing the HTTP-POST Delete Action Method 1. In this task, you will implement the HTTP-POST version of the Delete action method that will be invoked when a user clicks the Delete button. The method should delete the album in the database. 2. Close the browser if needed, to return to the Visual Studio window. Open StoreManagerController class. To do this, expand the Controllers folder and double-click StoreManagerController.[cs|vb]. 3. Replace HTTP-POST Delete action method code with the following: 3.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Handling Deletion HTTP-POST Delete action – CSharp)

Page 62 3.b. C# 3.c. // 3.d. // POST: /StoreManager/Delete/5

3.e.

3.f. [HttpPost] 3.g. public ActionResult Delete(int id, FormCollection collection) 3.h. {

3.i. var album = storeDB.Albums

3.j. .Include("OrderDetails").Include("Carts")

3.k. .Single(a => a.AlbumId == id);

3.l.

3.m. storeDB.DeleteObject(album);

3.n. storeDB.SaveChanges();

3.o.

3.p. return RedirectToAction("Index");

3.q. 3.r. }

3.s. 3.t. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Handling Deletion HTTP-POST Delete action – VB) 3.u. Visual Basic 3.v. ' 3.w. 'POST: /StoreManager/Delete/5

3.x. 3.y. 3.z. Function Delete(ByVal id As Integer,

3.aa. ByVal collection As FormCollection

3.ab. ) As ActionResult

3.ac.

3.ad. Dim album = storeDB.Albums.Include("OrderDetails").Include("Carts").Single(

3.ae. Function(a) a.AlbumId = id)

3.af.

Page 63 3.ag. storeDB.DeleteObject(album)

3.ah. storeDB.SaveChanges()

3.ai.

3.aj. Return RedirectToAction("Index")

3.ak. 3.al. End Function

Task 4 – Deleting on Cascade 1. Because of Referential Integrity, a deletion of an Album could raise an exception if it has OrderDetails entries. To solve this, you should allow cascade deletes. So, when you delete an Album, it will delete all the OrderDetails entries for that album. In this task, you will activate deletion on cascade.

2. Note: In this scenario you will delete an Album no matter if it has an order associated. Consider that in other application scenarios this could not be the correct action.

3. On the Solution Explorer expand the Models folder and then double-click StoreDB.edmx. This opens the Entity Data Model designer. 4. Open the Models/StoreDB.edmx entity diagram. Right-click the relation between Album and OrderDetail and select Properties.

Page 64 4.a.

4.b. Figure 32 4.c. Editing Properties of a Relation

4.d. 5. In the Properties window, set the End1 OnDelete value to Cascade.

Page 65 5.a. 5.b. Figure 33 5.c. OnDelete property

5.d.

Task 5 – Running the Application In this task, you will test that the StoreManager Delete View page lets you delete an Album and then redirects to the StoreManager Index View. 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager. Select one album to delete by clicking Delete. Confirm the deletion by clicking Delete button:

Page 66 2.a.

2.b. Figure 34 2.c. Deleting an Album

2.d. 3. Verify that the album was deleted since it does not appear in the Index.aspx page.

Next Step 1. Exercise 6: Adding Validation

Exercise 6: Adding Validation

1. Currently, the Create and Edit forms you have in place do not perform any kind of validation. If the user leaves a required field blank or type letters in the price field, the first error you will get will be from the database. 2. You can add validation to the application by adding Data Annotations to your model class. Data Annotations allow describing the rules you want applied to your model properties, and ASP.NET MVC will take care of enforcing and displaying appropriate message to users. Additionally, you will add client-side (AJAX) validation that will check all fields in the browser before being submitted to the controller actions.

Page 67 3. Task 1 – Adding Data Annotations 4. In this task, you will add Data Annotations to the Album Model that will make the Create and Edit page display validation messages when appropriate. 5. Start Microsoft Visual Web Developer 2010 Express from Start | All Programs | Microsoft Visual Studio 2010 Express | Microsoft Visual Web Developer 2010 Express. 6. In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex06- AddingValidation\Begin, select MvcMusicStore.sln and click Open.

6.a. Note: For a simple Model class, adding a Data Annotation is just handled by adding a using statement for System.ComponentModel.DataAnnotation, then placing a [Required] attribute on the appropriate properties. 6.b. The following example would make the Name property a required field in the View. 6.c. C# 6.d. using System.ComponentModel.DataAnnotations; 6.e. namespace SuperheroSample.Models 6.f. { 6.g. public class Superhero 6.h. { 6.i. [Required] 6.j. public string Name { get; set; } 6.k. public bool WearsCape { get; set; } 6.l. } 6.m. } 6.n. Visual Basic 6.o. Imports System.ComponentModel.DataAnnotations 6.p. Public Class Superhero 6.q. 6.r. Public Property Name As String 6.s. Public Property WearsCape As Boolean 6.t. End Class 6.u. This is a little more complex in cases like this application where the Entity Data Model is generated. If you added Data Annotations directly to the model classes, they would be overwritten if you update the model from the database. 6.v. Instead, you can make use of metadata partial classes which will exist to hold the annotations and are associated with the model classes using the [MetadataType] attribute. 6.w. 7. Add a new metadata partial class. To do this, right-click the Models folder within the Solution Explorer, select Add and then New Item.

Page 68 8. In the Add New Item dialog, select the Class template, located under Visual [C#|Basic] -> Web template list. Change the name to Album.[cs|vb] and click Add.

8.a.

8.b. Figure 35 8.c. Adding the Album class – C#

8.d.

Page 69 8.e.

8.f. Figure 36 8.g. Adding the Album class - VB

8.h. 9. Replace Album.[cs|vb] content with the highlighted code, so that it looks like the following: 9.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex6 Album metadata partial class – CSharp) 9.b. C# 9.c. using System; 9.d. using System.Collections.Generic; 9.e. using System.Linq; 9.f. using System.Web; 9.g. using System.ComponentModel; 9.h. using System.ComponentModel.DataAnnotations; 9.i. using System.Web.Mvc;

9.j.

Page 70 9.k. namespace MvcMusicStore.Models 9.l. {

9.m. [MetadataType(typeof(AlbumMetaData))]

9.n. public partial class Album

9.o. {

9.p. // Validation rules for the Album class

9.q.

9.r. [Bind(Exclude = "AlbumId")]

9.s. public class AlbumMetaData

9.t. {

9.u. [ScaffoldColumn(false)]

9.v. public object AlbumId { get; set; }

9.w.

9.x. [DisplayName("Genre")]

9.y. public object GenreId { get; set; }

9.z.

9.aa. [DisplayName("Artist")]

9.ab. public object ArtistId { get; set; }

9.ac.

9.ad. [Required(ErrorMessage = "An Album Title is required")]

9.ae. [DisplayFormat(ConvertEmptyStringToNull = false)]

9.af. [StringLength(160)]

9.ag. public object Title { get; set; }

9.ah.

9.ai. [DisplayName("Album Art URL")]

9.aj. [StringLength(1024)]

9.ak. public object AlbumArtUrl { get; set; }

9.al.

9.am. [Required(ErrorMessage = "Price is required")]

9.an. [Range(0.01, 100.00, ErrorMessage = "Price must be between 0.01 and 100.00")]

9.ao. public object Price { get; set; }

Page 71 9.ap. }

9.aq. } 9.ar. }

9.as. 9.at. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex6 Album metadata partial class – VB) 9.au. Visual Basic 9.av. Imports System.ComponentModel 9.aw. Imports System.ComponentModel.DataAnnotations

9.ax. 9.ay. 9.az. Partial Public Class Album

9.ba. 'Validation rules for the Album class

9.bb.

9.bc.

9.bd. Public Class AlbumMetaData

9.be.

9.bf. Public Property AlbumId As Object

9.bg.

9.bh.

9.bi. Public Property GenreId As Object

9.bj.

9.bk.

9.bl. Public Property ArtistId As Object

9.bm.

9.bn.

9.bo. DisplayFormat(ConvertEmptyStringToNull:=False),

9.bp. StringLength(160)>

9.bq. Public Property Title As Object

9.br.

9.bs.

9.bt. Public Property AlbumArtUrl As Object

Page 72 9.bu.

9.bv.

9.bw. Range(0.01, 100.0, ErrorMessage:="Price must be between 0.01 and 100.00")>

9.bx. Public Property Price As Object

9.by. End Class 9.bz. End Class

9.ca. Note: This Album partial class has a MetadataType attribute which points to the AlbumMetaData class for the Data Annotations. These are some of the Data Annotation attributes you are using to annotate the Album model: 9.cb. • Required – Indicates that the property is a required field 9.cc. • DisplayName – Defines the text to be used on form fields and validation messages 9.cd. • DisplayFormat – Specifies how data fields are displayed and formatted. 9.ce. • StringLength – Defines a maximum length for a string field 9.cf. • Range – Gives a maximum and minimum value for a numeric field 9.cg. • Bind – Lists fields to exclude or include when binding parameter or form values to model properties 9.ch. • ScaffoldColumn – Allows hiding fields from editor forms 9.ci.

9.cj. Note: The line [DisplayFormat(ConvertEmptyStringToNull=false)] indicates that empty strings from the model won’t be converted to null when the data field is updated in the data source. This setting will avoid an exception when the Entity Framework assigns null values to the model before Data Annotation validates the fields.

9.ck.

Task 2 – Running the Application In this task, you will test that the Create and Edit pages validate fields, using the display names chosen in the last task. 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager/Create. Verify that the display names match the ones in the partial class (like Album Art URL instead of AlbumArtUrl)

Page 73 3. Click Save, without filling the form. Verify that you get the corresponding validation messages.

3.a.

3.b. Figure 37 3.c. Validated fields in Create page

3.d. 4. You can verify that the same occurs with the Edit page. Change the URL to /StoreManager/Edit/388 and verify that the display names match the ones in the partial class (like Album Art URL instead of AlbumArtUrl). Empty the Title and Price fields and click Save. Verify that you get the corresponding validation messages.

Page 74 4.a.

4.b. Figure 38 4.c. Validated fields in Edit page

4.d.

Task 3 – Adding Client-Side (AJAX) validation In this task, you will add client-side (AJAX) validation to the forms to check all fields in the browser before being submitted to the controller actions. 1. Close the browser if needed, to return to the Visual Studio window. Open /Views/Shared/EditorTemplates/Album.ascx 2. Include the needed references to the libraries that will take care of the client-side validation: 2.a. HTML(C#) 2.b. <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 2.c. 2.d.

Page 75 2.e. 2.f.

2.g. 2.h. HTML(Visual Basic) 2.i. <%@ Page Title="" Language="VB" Inherits="System.Web.Mvc.ViewPage(Of MvcMusicStore.Album)" %> 2.j. 2.k. 2.l. 2.m.

3. Use the Html.EnableClientValidation helper method to turn on client-side validation. For both the Create and Edit view templates, add that call directly above the Html.BeginForm call. In order to do that, open /Views/StoreManager/Create.aspx and /Views/StoreManager/Edit.aspx and add the following: 3.a. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex6 Client-Side validation – CSharp) 3.b. C# 3.c. <% Html.EnableClientValidation(); %>

3.d.

3.e. <% using (Html.BeginForm()) {%>

3.f. <%: Html.ValidationSummary(true) %>

3.g.

3.h.

3.i. 3.j. (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex6 Client-Side validation – VB) 3.k. Visual Basic 3.l. <%Html.EnableClientValidation()%>

3.m.

Page 76 3.n. <% Using Html.BeginForm() %>

3.o. <%: Html.ValidationSummary(True) %>

3.p.

4. Edit the Web.config in the project root to disable UnobtrusiveJavaScript. To do this, replace the appSettings entry with the following one: 4.a. XML 4.b.

4.c.

4.d.

4.e.

4.f.

4.g.

Task 4 – Running the Application In this task, you will test that the Create and Edit pages validate fields in the browser before being submitted to the controller actions. 1. Press F5 to run the Application. 2. The project starts in the Home page. Change the URL to /StoreManager/Create. Enter a letter in the Price field and click anywhere else in the form, taking focus out of the text box. Verify that without submitting the form, the corresponding validation message appears.

Page 77 2.a.

2.b. Figure 39 2.c. Validated fields at client-side

2.d. 3. Delete the letter entered in the Price field and verify that the appropriate validation message appears without submitting the form.

Page 78 3.a.

3.b. Figure 40 3.c. Validated fields at client-side

3.d.

Next Step 1. Summary

Summary

1. By completing this Hands-On Lab you have learned how to enable users to change the data stored in the database with the use of the following: Controller actions like Index, Create, Edit, Delete ASP.NET MVC’s scaffolding feature for displaying properties in an HTML table Custom HTML helpers to improve user experience Action methods that react to either HTTP-GET or HTTP-POST calls A shared editor template for similar View templates like Create and Edit

Page 79 Form elements like drop-downs Data annotations for Model validation Client-side AJAX validation

Page 80

Recommended publications