BTI420 Lab 4

Work with a persistent store. Continue working with view model classes and objects.

.

BTI420 Lab 4 – Due on Thu Feb 6

Due date: Thursday, February 6, 2014, at 6:00pm ET

Grade value: 4% of your final course grade

.

Objective(s)

Work with a persistent store, and its program code components.

Get data from a user to add objects to the persistent store.

Continue to use and configure scaffolding when appropriate and useful.

Continue to use and configure HTML Helpers when appropriate and useful.

.

Introduction to the problem that you will solve

We need a web app that will enable a retail store worker to add new products that customers can buy.

The domain model is Suppliers and Products. 

Your web app will create a small number of Supplier objects when launched for the first time. It will also have a controller that will deliver a collection to a default view, and render that collection as a list (or more specifically, an HTML Table).

Your web app will enable the user to manage Product objects. Its ‘products’ controller will support these tasks:

  • Display all (in a list/table)
  • Display one selected
  • Add new product

Obviously, you will write views that render content (where appropriate).

Also, a ‘manager’ object will manage / mediate / coordinate / marshal data operations.

An example web app is posted here: bti420.azurewebsites.net

Your web app does NOT have to work or look exactly the same as the example web app.

Read/skim this assignment fully before you start work on it.

.

Get started with Lab 4

Create a new project. Its name will be “Lab4″.

Alternatively, you can download the “Lab4” project from the “Project_Templates” folder in this BTI420 course’s code example repository on GitHub, and use that as a base.

If you are using Visual Studio 2013 (and you should be using this version):

New project > ASP.NET Web Application > MVC > no authentication

If you are using Visual Studio 2012, use the procedure in Lab 0 to create the project.

.

Add and configure the persistent store components

As you recently learned (and covered in the January 29 class notes), add and configure the persistent store components.

  1. Use NuGet to add the Entity Framework to your project
  2. Add a connection string to your project’s Web.config
  3. Write design model classes for Supplier and Product
  4. Write a data context class
  5. Write a store initializer class, and code that will create three (3) supplier objects, and make it run when the web app launches

When your project has these components, it is ready for the remaining work.

.

Design model classes

design-model-classesThe Supplier design model class has these properties:

  • Id – int – identifier
  • Name – string
  • TypeOfBusiness – string
  • Country – string – head office location
  • NameOfCEO – string
  • YearStarted – int
  • Products – collection of Product

It (obviously) also needs a default constructor.

The Product design model class has these properties:

  • Id – int – identifier
  • Name – string
  • ProductId – string – part/model identifier
  • Size – string
  • UPC – string – universal product code
  • MSRP – double – suggested retail price
  • Supplier – Supplier

.

Incidentally, the diagram at the right was created in Visual Studio. Here’s how to create your own. (You do not have to do this. This task is not part of the specifications.)

In the Models folder, add a new item, a “class diagram”. A design surface appears in the editing panel.

Drag-and-drop your “DesignModelClasses.cs” object from the Solution Explorer to the design surface.

Adjust size and member display options, as desired. For the navigation properties, you can choose to show them as associations, which adds the arrows. A single arrowhead means “to one”, and a double arrowhead means “to many”.

The wrench icon glyph-property is a property. A box icon glyph-method is a method (which is usually the default constructor).

.

Write view model classes for Supplier

Two are needed for this web app:

  1. SupplierList, with only the data needed in a user interface ‘select/list’ control
  2. SupplierBase, with most properties

SupplierList needs the Id property and another property that’s useful when displayed in, for example, a drop-down list – maybe the supplier’s name?

vm-supplierlist

SupplierBase has most properties, but it does not need navigation properties.

vm-supplierbase

These two classes do NOT have an inheritance relationship.

.

Write view model classes for Product

The most important use case is the ability of a user to create a new Product object. This interaction has three steps or tasks:

  1. Display a data entry form
  2. Gather user input
  3. Display the result

Each will require a view model class:

Step / Task View model class, suggested name
Display a data entry form ProductAddForm
Gather user input ProductAdd
Display the result ProductBase

.

The following illustrates some of the important concepts behind task 1.
(Click to view it full-size in a tab/window.)

map-productaddform-to-view

.

The following illustrates some of the important concepts behind task 2.
(Click to view it full-size in a tab/window.)

map-productadd-to-controller

.

ProductAddForm view model class

The purpose of this view model class is to build an object that will deliver data that’s needed to render the view.

An example view is shown below:

display-data-entry-form

Name, ProductId, and UPC will be string properties. MSRP will be a double.

What about the radio button group, and the drop-down list user interface controls? What data do we send to render the view?

We send a SelectList object for each control.

Before continuing, read this document to learn more about configuring a view model object with a SelectList object.

Welcome back.

As suggested above, the name of the view model class will be ProductAddForm. It will look like this:

vm-productaddform

In the view code for the radio button group control, the value of each “name” attribute must be “Size”. When the HTML Form posts back to the server, the posted data will include data that looks like this: Size=Medium

In the view code for the drop-down list control, you must use “SupplierId” for the name of the <select…> element that is generated by the DropDownList() HTML Helper method. When the HTML Form posts back to the server, the posted data will include data that looks like this: SupplierId=123

.

ProductAdd view model class

The purpose of this view model class is to describe the object that will be submitted by the user when the HTML Form posts back to the server.

The radio button group is a single-selection control, so it will post back a single string value.

The drop-down list is also a single-selection control, so it will post back a single value that will be converted to an int.

As suggested above, the name of the view model class will be ProductAdd. It will look like this:

vm-productadd

.

ProductBase view model class

The purpose of this view model class is to describe the object that will be delivered to a view, for display in a list (i.e. an HTML Table) or on its own.

ProductBase inherits from ProductAdd, and therefore has all its properties. In addition, it has two more:

  • Id – int – the object identifier
  • SupplierName – string – the value of the Name property in the Supplier of the Product object

As suggested above, the name of the view model class will be ProductBase. It will look like this:

vm-productbase

.

Create and write a Manager class

In the Controllers folder, create a class source code file named Manager.cs.

Add another “using” directive, for the Lab4.Models namespace.

Add a private field near the top of the code block:
private DataContext ds = new DataContext();

This reference will enable all your methods to get access to the persistent store. You will write these methods:

public IEnumerable<SupplierBase> GetAllSuppliers()

public IEnumerable<SupplierList> GetAllSuppliersList()

public IEnumerable<ProductBase> GetAllProducts()

public ProductBase GetProductById(int id)

public ProductBase AddNewProduct(ProductAdd newItem)

public List<string> GetProductSizes()

.

“Get all suppliers” method

Get all Supplier objects from the persistent store, sorted by name.

Create a collection of SupplierBase objects, and use code to map each Supplier object to a SupplierBase object.

Return the collection of SupplierBase objects.

.

“Get all suppliers, to be used in a select list” method

Similar technique to the method above, except that you will map to SupplierList objects.

.

“Get all products” method

Similar technique to the “get all suppliers” method above, except that you will map to ProductBase objects.

.

“Get specific product by its identifier” method

Attempt to fetch a single Product object, using the passed-in identifier. If null, return null. Otherwise, continue.

New: When you fetch the Product object, you must also fetch the associated Supplier object, using the Include() method:
var fetchedObject = ds.Products.Include(“Supplier”).SingleOrDefault(i => i.Id == id);

Create a ProductBase object, and use code to map the Product object to the ProductBase object.

Return the ProductBase object.

.

“Add a new product” method

The first task must be to validate the incoming SupplierId value. Therefore, attempt to fetch a single Supplier object, using the SupplierId value. If null, return null, otherwise continue.

Create a new Product object, and use code to map the incoming ProductAdd object to the Product object. Make sure that you set the Product object’s “Supplier” property to the Supplier object you just fetched above.

Add the new Product object to the persistent store collection (and make sure that you save changes).

Next, create a ProductBase object, and use code to map the Product object to the ProductBase object.

Return the ProductBase object.

.

“Get the product sizes list of strings” method

Create and return a list of strings for the Size property of a Product object. We suggest “Small”, “Medium”, and “Large”.

.

Products controller and views for ‘get all’ and ‘get one’

Create a controller named ProductsController. On the “Add Scaffold dialog, select “MVC 5 Controller with read/write actions”.

controller-add-scaffold

.

Add a private field near the top of the code block:
private Manager m = new Manager();

This reference will enable all your methods to get access to the manager object.

Index() method and view

Call the manager object’s “get all products” method.

Return the results to the view.

Add a view. You can (should) use scaffolding. Use the “List” template. Select “ProductBase” as the model class.

You can edit the view if you wish to improve it.

Details(int id) method and view

Call the manager object’s “get specific product by its identifier” method.

If null, redirect to the index view.

Otherwise, return the fetched object to the view.

Add a view. You can (should) use scaffolding. Use the “Details” template. Select “ProductBase” as the model class.

.

Products controller and views for ‘add new’

The scaffolder created “create” methods to handle HTTP GET and POST.

Create() method and view; handles HTTP GET (to display the HTML Form)

Create a new ProductAddForm object.

Configure its SelectList properties with data, as you recently learned.

Send the ProductAddForm object to the view.

Add a view. You can hand-code it (using the “Empty” template), or you can use scaffolding. If you want scaffolding, use the “Create” template, and “ProductAddForm” as the model class.

You will have to edit the view. Make it look and work similar to the code example.

Create(ProductAdd newItem) method; handles HTTP POST

Make sure the incoming ProductAdd object is valid, using the ModelState.IsValid check.

If not valid, redirect to the index view.

If valid, attempt to add the new item, using the manager object’s “add a new product” method.

If the attempt fails, redirect to the index view.

If successful, redirect to the details view so that the user can see the results of the ‘add new’ interaction.

.

Suppliers controller and views for ‘add new’

Create a suppliers controller (you can use the simpler “Empty” scaffold that has only the Index() method).

Add a view for the Index() method, using the “List” template, and the “SupplierBase” model class.

.

Configure (fix) navigation in your web app

Add links to the new page hierarchy in an appropriate place.

Maybe on the web app’s (Home) Index.cshtml view (in the body). Maybe also in the menu in _Layout.cshtml.

.

Submit your work on My.Seneca/Blackboard

Follow these brief instructions to submit your work on My.Seneca/Blackboard. See Lab 1 for all the detailed steps.

1. Make a copy of your “Lab4″ project

2. Remove the “packages”, “bin”, and “obj” folders

3. Zip your project (make sure you’re at the correct level in the file system)

4. Submit your work via My.Seneca/Blackboard

.

.

.

.

.

.

.

.

.

.

.

.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: