BTI420 Assignment 6

Working with a many-to-many association, “edit existing” use case.

Read/skim all of this document before you begin work.


Due date

Sunday, March 5, 2017, at 11:00pm ET

Notice that this due date is at the end of study week, so you can take your time and do this right.

Grade value: 5% of your final course grade




Work with many-to-many associated data, with “edit existing” functionality. Your web app will enable users to work with Playlist objects.


Introduction to the problem to be solved

We need an app that will enable a browser user to view and edit playlists.


Specifications overview and work plan

Here’s a brief list of specifications that you must implement:

  • Follows best practices
  • Implements the recommended system design guidance
  • Customized appearance, with an added menu item
  • Displays invoice and associated data

Here is a brief work plan sequence:

  1. Create the project, based on the project template
  2. Customize the app’s appearance
  3. Create view models and mappers that cover the use cases
  6. For the playlist entity, implement the “get all” and “get one” use cases; including controller code, and views
  7. For the playlist entity, implement the “edit existing” use case; including controller code, and view





Getting started

Create a new web app, named Assignment6. It MUST use the “Web app project v1” project template.



Customize the app’s appearance



Follow the guidance from Assignment 1 to customize the app’s appearance.


Overall goal: Enable basic editing

The overall goal is to enable basic editing of a playlist. The following image shows what you may end up with at the end of this assignment. Click to open the image full-size in a new tab/window.



Study the image. It shows a list of existing tracks on the playlist on the right side of the page. On the left, it shows a list of ALL tracks, whether on the playlist or not. The browser user can use the checkboxes to edit the content of the playlist.

To render this view, it will need one select list object, and a collection:

  • The select list will be used to render the checkboxes
  • The collection will hold the track objects on the existing playlist


Create view models and mappers that cover the initial use cases

The most logical starting point for the app will be to display a list of playlist objects.

Therefore, you will need a PlaylistBase view model class.

Next, you will need another view model class to hold details, and the most important details is a collection of track objects.

This in turn implies that you will need a TrackBase class.

The “edit existing” task will need another two view model classes:

  1. A view model class named (maybe) PlaylistEditTracksForm, to hold the data that is needed to render the HTML Form
  2. A view model class named (maybe) PlaylistEditTracks, to hold the data submitted by the browser user

As noted in the previous section, the “…Form” view model class will yes, need a select list property (for multiple selection). It will also need another property, to hold the collection of tracks that are on the current playlist.

As you have learned, the “…Form” view model class needs identification information. The object identifier, for sure, and obviously. And text to display to the browser user.

Remember, you will also need mappers.


Add methods to the Manager class that handle the use cases

Methods to handle “get all” playlists, and “get one” playlist, are needed.

As you have seen with other associated-item scenarios, the “get one” method will fetch the associated object(s). Therefore, “get one” playlist must fetch its track objects.

In addition, the “edit existing” playlist method will be needed. It will use the standard pattern for editing a to-many association of objects, as seen in the AssocManyToMany code example, and in the recent class notes.

Now, stop for a moment, and think about the “edit playlist” task. Presumably, you will create a page that will show or identify the playlist-being-edited. To edit/select the tracks on the playlist, the page will also have to show a list of tracks, in an item-selection element.

Therefore, in the Manager class, you will also need a “get all” tracks method.


Add controller(s), with code to work with the manager object

Add a controller for the playlist entity.


including controller code, and views

In the playlist controller, add the standard methods for “get all” and “get one”.

Generate the “get all” view. It should look something like the following. Click the image to open it in a new tab/window.



How did the middle column – Number of tracks on this playlist – get generated?

Two changes – one in the view model class, and one in the Manager class.

In the PlaylistBase class, add an int property named “TracksCount”. This name is important. It is a composed name. For a specific playlist object, which has a navigation property named “Tracks”, it will fetch/render the “Count” property of the “Tracks” object. Wait – there’s no property named “Count” in the design model class – where is that defined? Well, “Count” is a property of the collection.

Then, in the Manager class, edit the “get all” method, so that it includes the “Tracks” property in the fetch.

Finally, render this column in the view. If you want the number to show up as a Bootstrap badge, you can do that too.


Generate the “get one” view. It will need hand-editing, to render the collection of Track objects (wrapped in <p> or <span> elements, your choice). It should look something like the following. Click the image to open it in a new tab/window.



including controller code, and view

Now, you’re ready to implement the “edit existing” use case. If you wish, you can use the pair of method stubs in the controller that the scaffolder created for the edit task, to get started. Use the familiar pattern to code the rest of the methods.

You should know by now that the purpose of the GET method is to prepare and configure the “…Form” view model object, and send it to the view, so that an HTML Form can be created.

Create a “…Form” object. Configure it. In addition to identification property values, it will need:

  • A select list object, configured with 1) all possible tracks, and 2) the identifiers for the tracks that are currently associated with the playlist
  • A TrackBase collection, configured with the tracks that are currently associated with the playlist


Generate and edit the view

Generate the view. As you have learned, the scaffolder does not render collections or item-selection elements.

At the end of this task, the plan is to end up with a view that was first shown above. Here’s how. First, notice how the page is designed:



If you want the playlist name to appear as you see it above (with a light blue background), then surround it with a <span> element that uses one of the Bootstrap contextual backgrounds.

How do we get a two-column layout? With the Bootstrap .row and .col-xx-xx classes. Here’s how to make the container:

  1. Add a <div> element with class=row
  2. Inside this container, add two more <div> elements
  3. The left side will take two-thirds of the width, or 8/12 of the grid system layout, therefore, add class=col-md-8 to the first (left-side) container
  4. Then, add class=col-md-4 to the second (right-side) container

In the left-side container, add code for the checkbox group that displays all possible tracks. (The image is showing the result of standard <input type=checkbox… elements.)

How did we render the track name, composer, track time/length, and unit price? By adding a read-only property (which is a property that does not have a “set” accessor), and then using that in the select list object’s constructor. Here’s an example of how you can add a read-only property in a view model class:

// Composed read-only property
public string NameFull
    var ms = Math.Round((((double)Milliseconds / 1000) / 60), 1);

    var composer = string.IsNullOrEmpty(Composer) ? "" : ", composer " + Composer;
    var trackLength = (ms > 0) ? ", " + ms.ToString() + " minutes" : "";
    var unitPrice = (UnitPrice > 0) ? ", $ " + UnitPrice.ToString() : "";

    return string.Format("{0}{1}{2}{3}", Name, composer, trackLength, unitPrice);


The right-side container will have code for the <p> elements that hold the track names now on the playlist.

If you want the right-side container to have a grey background with rounded corners, simply add one of the Bootstrap well classes.


Code the method that processes the data submitted by the browser user

The incoming data will include the playlist identifier, and an int collection, with the identifiers of the tracks that will be on the playlist. Pass them on to the manager method. A successful result will redirect to the “details” view.


Testing your work



Reminder about academic honesty



Submitting your work

































%d bloggers like this: