Syllabus Schedule Project Canvas Assignment 1 Assignment 2 Assignment 3 Assignment 4

Assignment 1 - Entity Framework

Many e-commerce sites need a convenient and reliable method for non-technical people to maintain product and customer information. Providing clients with direct access to the database is risky since it allows them to inadvertently delete data, change settings, modify key fields, enter invalid data, etc. A better approach is to provide a web interface that validates inputs, allows access to only the fields that are needed to maintain the content, maintains referential integrity between database tables and provides a convenient way to upload product images. In this exercise you will construct administration pages with authentication for managing products in simple e-commerce site.

An admin back-end requires CRUD functionality for adding product information, product categories, customer information, etc. Hand coding controllers and views is time consuming so we will utilize Microsoft's Entity Framework (EF) and the model and view building wizards in Visual Studio (VS). Visual Studio include wizards that use EF to generate models from a database, generate databases from models, and create controllers and views with CRUD functionality. In this exercise you will complete a Microsoft tutorial that creates models and views from a database. You will then repeat the process using a simple retail store database.

These assignments are new. If you notice a significant problem or error please notify Professor Sandvig.

New Project

  1. Students This exercise uses "EF Database First" to generate models, controller, and views from a database. The database has three entities: students, courses, and enrollments. There is a many-to-many relationship between students and courses with enrollments as the associative table. Steps:
    1. Use Visual Studio 2017 to create a new Project named mis424Assignments. In VS select "ASP.NET Web Application C#, MVC, and authentication is Individual User Accounts. See image on right.
    2. Read the introduction of the tutorial Getting Started with Entity Framework 6 Database First Using MVC 5.
    3. Create database as in MIS 324: right-click "App_Data", Add, Sql Server Database, name your database "ContosoUniversityData". (ignore the tutorial for this step).
    4. Create three database tables by double-clicking on the database in Solution Explorer. This will open to Server Explorer. Right-click on the database and select "New Query." Search the tutorial for the phrase "Create table". Cut, paste, and execute each of the three Sql "create table" statements from the tutorial.
    5. Populate the tables by using the "Merge" script from the tutorial.
    6. Check database: Open the database to confirm that the three tables were created and populated with data.
    7. Generate models: Now the magic! Follow the steps in Generate the models. (Note: the model should be located inside the model folder. Make sure to right-click on the model folder as shown in the tutorial).  If asked "Choose Data Source" select "SQL Server Database File." The wizard should automatically see your database ContosoUniversityData.mdf and "Save connection settings in Web.Config as: should be checked. In "which database objects do you want to include in your model?" check "Tables" and click Finish. The wizard will create the model "ContosoModel" in your root folder and display the model in a ER diagram as shown in the tutorial.
    8. Housekeeping: If ContoscModel.edmx is located in the root folder of your application drag it into the "Models" folder before generating the views.
    9. Build your project (ctrl-shift-b)
    10. Generate the controller and views for "students" and "enrollments" as described in the next stop of the tutorial. Make sure to generate the controller inside the controller folder by right-clicking in the controller folder, selecting "Add",  "Controller", "MVC 5 Controller with views, using Entity Framework."
    11. Test! You should have CRUD functionality for students and enrollments. You (and VS wizards) have created a model with three entities, two controllers each with eight action methods, 10 views, and code that queries the database. This would take many hours to hand code.
    12. Navigation. Add a link from enrollments/index.cshtml to students/index.shtml and visa versa. Syntax:
      <a href="~/students/">Students</a>
      
    13. Publishing to server: You will need two connection strings: one for Visual Studio (localDb) and one for the server (SqlServerExpress). Improve the readability of the connection string that was created by Visual Studio by adding line breaks (as shown below). Make a duplicate and edit the copy as described in How to Convert a LocalDB Connection String to SQL Server Express. The changes are highlighted below. Comment out the localDB version and publish to the server. 
       <add name="ContosoUniversityDataEntities" 
       connectionString="metadata=res://*/Models.ContosoModel.csdl|
               res://*/Models.ContosoModel.ssdl|
               res://*/Models.ContosoModel.msl;
               provider=System.Data.SqlClient;  
               provider connection string=  
                   "Data Source=.\SQLEXPRESS;
                   AttachDbFilename=|DataDirectory|\ContosoUniversityData.mdf;
                   User Instance=True;
                   Integrated Security=True;
                   MultipleActiveResultSets=True;
                   App=EntityFramework""
                   providerName="System.Data.EntityClient"/>
      
    14. web.config: As in MIS 324 I suggest removing your web.config file from being published when you publish your solution. Select properties, Build Action: None.
    15. Done!
  2. retail/admin - The next few exercises will build a simple retail store front-end with a administrative back-end for managing product information. The administrative back-end will full CRUD functionality for product, categories, and product-categories as well as image uploading and resizing. This first exercise creates the database and full CRUD functionality for managing products. Use of the Entity Framework greatly reduces the time needed for development. In this exercise without writing any code you will create three controllers and 15 views for managing data. The only code you will write are a few navigation links between the views.

    The admin username/password for the sample is "admin@wwu.edu" and "Admin.1". Please use the same username/password on your exercises for grading purposes.

    Steps:

    1. Use the same project "mis424Assignments" that you created in the previous exercise. Create a new database named "RetailStore" with three tables: Product, Category, ProductCategory. The fields for Product and Category are shown in the images. ProductID and CategoryID fields are both primary key and identity (auto number). Use the following SQL code for ProductCategory. Note that it uses an identity field named ID rather than a composite key which is more typical for associative tables. Referential integrity is enforced using constraints rather than primary keys. The ID field is needed for EF to create a model for this table.
      CREATE TABLE [dbo].[ProductCategory] (
          [ID]         INT IDENTITY (1, 1) NOT NULL,
          [ProductID]  INT NOT NULL,
          [CategoryID] INT NOT NULL,
          PRIMARY KEY CLUSTERED ([ID] ASC),
          UNIQUE NONCLUSTERED ([ProductID] ASC, [CategoryID] ASC),
          CONSTRAINT [FK_dbo.ProductCategory_dbo.Product_ProductID] FOREIGN KEY ([ProductID]) 
                REFERENCES [dbo].[Product] ([ProductID]) ON DELETE CASCADE,
          CONSTRAINT [FK_dbo.ProductCategory_dbo.Category_CategoryID] FOREIGN KEY ([CategoryID]) 
                REFERENCES [dbo].[Category] ([CategoryID]) ON DELETE CASCADE
      );               
    2. entity framework retail modelCreate a ADO.NET Entity Data Model named "RetailStoreModel" as in the previous exercise. Make sure the model is located in the Model folder.
    3. Compile your project.
    4. Use VS's scaffolding feature to create CRUD controllers and views using Entity Framework for the three tables: Product, Category, and ProductCategoy.
    5. Test by adding a couple of test categories, products, and product categories.
    6. The admin pages needs navigation to its features. Create a new empty controller named "RetailController" and add an action method and view named "Admin". Add links to the admin pages created in the previous step.
      <ul>
          <li><a href="~/products/">Edit Products</a></li>
          <li><a href="~/categories/">Edit Categories</a></li>
          <li><a href="~/productCategories/">Edit Product Category</a></li>
      </ul>
      
    7. The admin index views need links to the admin home page. Add the following tag to the index views for editing Product, Category, and ProductCategory data.
      <p>
          <a href="~/retail/admin/">Return to Admin home</a>
      </p>
      
    8. Test by adding a couple of products, categories, and product categories. The products sold by your store can be anything you like as long as they are legal, tasteful and images are available (ideas: dogs, cats, flowers, birds, books, music, videos, jewelry, ...). The sample site sells photographs.

  3. retail/admin -- Many e-commerce sites need a convenient method for uploading and resizing images. In this exercise you are provided with a simple image upload and resize utility. You will modify it to save each image in three different sizes.
    1. We will put the functionality for the file upload into the Admin view. The first answer by Darin Dimitrov to File Upload ASP.NET MVC describes how to upload files. (Aside: Darin Dimitrov is a top 0.01% StackOverflow contributer and has received eight Microsoft Valuable Professional (MVP) awards. Impressive.) Add the code for the HTML form to Views/Retail/Admin.cshtml which you created previously. The form should to post to the admin action method of the RetailController so change "Index", "Home" to "Admin", "Retail"
    2. Upload code
      1. The code for writing the file to the server will be located in the RetailController. Copy the code snippet from the answer starting at [HttpPost]. Change its name from Index to Admin (since it is handling the post from Admin.cshtml).
      2. This code requires the "using System.IO;" directive at the top of the controller.
      3. The sample code puts the images in the App_Data folder. A better location for the files would be /content/ProductImages so modify the path in the MapPath statement.
      4. Also add a folder named ProductImages to the content folder.
      5. Replace redirectToAction with View().
    3. Test by uploading an image. Note: to see the uploaded file in VS solution explorer you will need to click the "show all files" icon at the top of the window.
    4. For security we want to limit upload to images only. Add the following snippet inside the "if" statement before the file is written:
         string extension = Path.GetExtension(file.FileName).ToLower();
         if (!(extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".gif"))
         {
             ViewBag.message = "Invalid image extension: " + extension;
             return View();
         }
      
    5. Add @ViewBag.message to admin.cshtml to output the message.
    6. Give the user confirmation that their file has uploaded by adding:

      ViewBag.message = "Image successfully uploaded: " + fileName;

    7. The uploaded images need to be displayed on the admin page. The first answer by Freeman to How to show images from a folder using Razor MVC? shows how. Copy the code to admin.cshtml. His code shows only .jpg. Change "*.jpg" to "*.*" to show all files.
    8. uploaded imageThe next step is to resize the images to sizes appropriate for the web site. We will follow Amazon's example and create three sizes for each image. The first answer by Maxs87 shows How to resize and save an image which uploaded using file upload control in c# provides the code. In the Admin action method replace "file.SaveAs(path);" with the four lines of code from the solution. Remove the quotes around "path". The code uses the namespace WebHelpers so add "using System.Web.Helpers;" to the page directives. Fortunately the WebImage.Resize retains the height-width ratio of the image saving us the trouble of calculating appropriate dimensions.
    9. Change the resized file size from 1000 to something more modest, such as 500. Test with an image. Check that the image has the correct dimensions.
    10. Repeat sizing and saving three times at sizes of approximately 200, 400, 600. The following code snippet shows one way this could be done:
         
         int[] sizes = { 600, 400, 200 };
         foreach (int size in sizes)
         {
             img.Resize(size, size);
             int dot = path.LastIndexOf(".");
             string path2 = path.Insert(dot, "." + size);
             img.Save(path2);
         }
      
    11. Images can be reduced in size but enlarged images are grainy. The user should be warned when the uploaded image is too small, something like this:
        if (img.Width < 600 && img.Height < 600)
        {
            ViewBag.message = "Please use a larger image. Should have one dimension >= 600px. ";
            return View();
        }
      
    12. Test!
    13. Finally, we need a way for the user to delete files. In the admin view add hyperlinks under each image that point to an action method named "DeleteImage" and pass the image name as a parameter.
      <a href="~/retail/DeleteImage?ImageName=@img.Name">delete @img.Name</a>
      
    14.  In the retail controller add code similar to the first answer by Damith in ASP NET MVC 5 Delete File From Server.
        public ActionResult DeleteImage(string ImageName)
        {
            string fullPath = Request.MapPath("~/content/ProductImages/" + ImageName);
            if (System.IO.File.Exists(fullPath))
            {
                System.IO.File.Delete(fullPath);
            }
            ViewBag.message = "Image successfully deleted: " + ImageName;
            return View("admin");
        }
      
    15. publish allThe default publish configuration in VS is to publish only files needed to run the application. You also need it to publish your ProductImages folder. Go to application properties and change the Package/Publish Web deploy setting to "All files in this project folder."
    16. Finished for this week. Next week you will add security to the admin pages, an improved interface for assigning productCategories, and a retail front end.

Submission instructions: Submit assignments via the Canvas course management system. Submit the full URL for each exercise in the assignment, listing the URLs in the same order that they are listed in the assignment. To minimize typos in URLs it is strongly recommended that you copy the URLs from the address bar of the browser rather than trying to type them. Incorrect URLs will not be graded and no credit will be given.

When pages are connected via navigation it is only necessary to submit the URL of the first page.

Regular Expressions HTML Color Names Color Picker ASCII Character Codes Unicode Character Codes
Top