MarkAFarrugia

Freelance Web Development in Malta

By

ASP.NET MVC 4 ViewBag and Dropdownlists

First of all I would like to welcome any first time visitors to my blog. Before I start this blog I would like to give a brief introduction to myself. My name is Mark Anthony Farrugia and, apart from being a Computing Teacher, I am a freelance web developer based in Malta,a small island in the Mediterranean. So now let me start this blog post :) .

The outcomes of this blog are to

  1. Discover what is the ViewBag and how this can be used to return data back to a View
  2. Use a DropdownList to display data for a foreign key column

The prerequisites to follow this blog are

  1. You should have SQL Server Express installed. You can install it from here
  2. You should have two tables Products and Categories inside your database
  3. You should have some understanding of LINQ To Entities

This blog will explain how you can give the opportunity to a user to select a Product Category from a dropdown list, for a specific Product. In the previous blog we saw how the user had to input the CategoryId manually. This, of course, is not the ideal situation since the user would have to remember all the ids for all the Product Categories manually.

So basically, the first thing we should be doing is to create a method which returns all Product Categories from our database. This method should be included in our business class which is included in our Models folder. This code is shown underneath.

/// <summary>
 /// Gets all product categories
 /// </summary>
 /// <returns>All product categories.</returns>
 public IQueryable<Category> GetCategories()
 {
 Models.MVCBlogDBEntities entities = new MVCBlogDBEntities();
 return entities.Categories;
 }

Once we are finished from our business method we need to call this method from our controller method. Basically, this information should be displayed in our ASP.NET MVC View, using a DropdownList. To display this information we need to make use of the SelectListItem which represents one single dropdown option made up of the Text and the Value. The Text property is the text which the user sees in the dropdown whilst the Value is the value stored for the option selected.

Let’s assume we wish to include our DropdownList inside the Create controller method, which basically serves as the controller which adds a new product.  The underneath code is the code snippet inside our controller method which basically creates a List of SelectListItems. For each SelectListItem we are setting its Value to the CategoryId, whilst we are setting its Text to the CategoryName. This would mean that we will be storing the CategoryId inside the ProductCategory foreign key whilst displaying the CategoryName.

[HttpGet]
public ActionResult Create()
{
 List<SelectListItem> Categories = (from p in
 new Models.DBProducts().GetCategories().ToList()
 select new SelectListItem()
 {
 Value = p.CategoryId.ToString(),
 Text = p.CategoryName
 }).ToList();
ViewBag.ProductCategory = Categories;
 return View();
 }

On line 11 I will then make use of the ViewBag which is a special object to pass the List of all SelectListItems back to the respective View. The ViewBag is no more than a container of objects which can then be accessed from the ASP.NET MVC View. You can place any object in the ViewBag and then access it using from the MVC View. We are naming the ViewBag variable ProductCategory so that it would have the same name as our ProductCategory field which can be found in the Products table. Recall that in our previous blog we ensured that the fields, found inside our ASP.NET MVC view, had the same names as the table’s fields found in our database. This will enable ASP.NET MVC to map the field values to their relevant database column fields.

Now let’s concentrate on how we will display the DropdownList in our ASP.NET MVC View. This can be done by using the DropDownList helper as shown in the underneath code. You should ensure that the name given is the same as the name given in the ViewBag found in our controller method.

@Html.DropDownList("ProductCategory")

If you run your ASP.NET MVC application and navigate to the Create Product controller method you should end up with a page like the one shown in Figure 1.

Figure 1 - Dropdownlist in View

Figure 1 – How the DropDownList will be shown in your ASP.NET MVC View

The actual HTML which is created is then shown underneath.

<select id="ProductCategory" name="ProductCategory"><option value="1">Motherboards</option>
<option value="2">CPU</option>
</select>

Note that each Category SelectListItem we have created in our Controller is represented by an HTML Option. We are storing the CategoryId as the Value whilst we are showing the CategoryName back to the user.

I hope that you found this blog interesting and that you have learned how to use DropdownLists in ASP.NET MVC.

By

Adding, Editing and Deleting data using ASP.NET MVC

First of all I would like to welcome any first time visitors to my blog. Before I start this blog I would like to give a brief introduction to myself. My name is Mark Anthony Farrugia and, apart from being a Computing Teacher, I am a freelance web developer based in Malta, a small island in the Mediterranean. So now let me start this blog post :) .

In the previous blog I have gone into the detail of how an ASP.NET MVC View can be used to display data. We also went into the details of how some of the ASP.NET MVC helper controls work and how they can be used.

At the end of this blog you should have an understanding of how to

  1. Create an MVC view to ADD a product
  2. Create an MVC view to EDIT a product
  3. Create an MVC view to DELETE a product

The prerequisites for this blog are

  1. Follow the previous blog where I explained how to create a View which lists all products and where for each products the user would have the possiblity to add/edit and delete products.
  2. Ensure you have a Products table inside an SQL Express table and that you have defined your LINQ To Entities model. You can follow this blog if you still haven’t done so.

So let’s start by creating the View which will add a new product. We will be creating two controller methods called Create which one will be decorated with an HttpGet used to display the View, while the other one will be decorated with an HttpPost which will be used to post the products information and adds the product to the database.

The HttpGet CreateNew method is shown underneath. You will note that this method only returns the respective View related to this controller.

[HttpGet]
public ActionResult Create()
        {
            return View();
        }

Now click the right mouse button inside the Create method and click on Add View. You should ensure that you create a strongly typed view of type Product. The ScaffoldTemplate should be Create since this View will be used to create a new product. This is also shown in Figure 1.

CreateNew Add View Template

Figure 1 – The CreateNew template which ASP.NET MVC makes available to create an ASP.NET MVC view which creates new records.

You will note that the new View which is created contains all the fields which a single Product entity has and this is shown underneath.

@model MVCForBlog.Models.Product
@{
    ViewBag.Title = "CreateNew";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>CreateNew</h2>
@using (Html.BeginForm())
 {
    @Html.ValidationSummary(true)
<fieldset><legend>Product</legend>
<div class="editor-label">
@Html.LabelFor(model => model.ProductName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProductName)
 @Html.ValidationMessageFor(model => model.ProductName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ProductCategory)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProductCategory)
 @Html.ValidationMessageFor(model => model.ProductCategory)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ProductDescription)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProductDescription)
 @Html.ValidationMessageFor(model => model.ProductDescription)
</div>
 <input type="submit" value="Create" />
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Let me explain some new constructs which are included in this form. On the first line you have the following code @model MVCForBlog.Models.Product. This means that this View accepts a single Product instance.

On line 7 there is a tag which is Html.BeginForm. This is basically a construct which will then be rendered as a form tag which will post to the Create controller method which will then be used to add a new product and which we will be creating shortly. The HTML tag which is rendered when your MVC application runs is shown underneath

<form action="/products/Create" method="post">

On line 32 then there is an HTML submit button which will be used to submit the information on the form back to our Create controller method.

Before creating the Controller method which will be used to add a new Product we need to add the method in our business class which is located inside our Models folder. This method will actually add our product back to the database. This will be done using LINQ To Entities. This code is shown underneath and as you can see there is nothing complex which is being done. I am just actually adding a new Product instance back to the database.

/// <summary>
 /// Adds a new product back to the database.
 /// </summary>
 /// <param name="NewProduct">New product to be added.</param>
 public void AddProduct(Product NewProduct)
 {
 Models.MVCBlogDBEntities entities = new MVCBlogDBEntities();
 entities.Products.AddObject(NewProduct);
 entities.SaveChanges();
 }

Now let’s go back to our Create (HttpPost) controller method and let’s call this newly created method as shown in the underneath code.

[HttpPost]
 public ActionResult Create(Models.Product NewProduct)
 {
 Models.DBProducts dbproduct = new Models.DBProducts();
 dbproduct.AddProduct(NewProduct);
 return RedirectToAction("Index");
 }

Now let me explain how the above code works. As you will note the method Create accepts a Product instance parameter. This Product instance parameter will be filled from the Create View in our ASP.NET MVC project. Basically what MVC does is that it maps the Html fields to our Product entity model. So for example, if one of the Product’s field name is ProductName, and you have a textbox in your html with its Name set to ProductName, its value will be mapped to the Product’s ProductName field.

This way you can pass a whole object in the Controller method and be sure that all fields will be filled automatically. Recall that when we created the Create View we used some special ASP.NET MVC constructs such as  @Html.EditorFor(model => model.ProductName) which actually maps to our Product table.

So basically once the user clicks on Create button, in the Create view, the Product instance is passed back to our Create (HttpPost) controller method and the Product is added back to our database. The code at line 6 then basically redirects us to the Products Index controller method which actually lists all products.

Now that we have created the Controller method which creates a new product, let’s create the one which edits an existing product. Before we can create this controller, we have to create a method which returns one single Product according to a ProductId which is passed. This method should be created inside the Models folder inside our business class as shown underneath.

/// <summary>
 /// Gets one single product according to an id which is passed.
 /// </summary>
 /// <returns>One single product according to product id which is passed.</returns>
 public Product GetProduct(Guid ProductId)
 {
 Models.MVCBlogDBEntities entities = new MVCBlogDBEntities();
 return entities.Products.SingleOrDefault(p=>p.ProductId == ProductId);
 }

Now let’s create a Controller method called Edit as shown in the underneath code which calls the method which we have created. Note that whilst in the Create controller method we are not returning any object back to the view, in this case we are returning one single product back to the View. The View then displays this product.

[HttpGet]
 public ActionResult Edit()
 {</pre>
Models.DBProducts db = new Models.DBProducts();
return View(db.GetProduct(id));
}
<pre>

Let’s create a View which our ScaffoldTemplate is Edit as shown in Figure 2.

Edit Product View

Figure 2 – ASP.NET MVC View which edits an existing product.

The Edit View MVC code is shown underneath. As you will note the code resembles the Create ASP.NET MVC View. In fact we can say that it is practically the same view with the different that this View will be used to edit a specific product rather than adding a new product.

@model MVCForBlog.Models.Product
@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Product</legend>

        @Html.HiddenFor(model => model.ProductId)

        <div class="editor-label">
            @Html.LabelFor(model => model.ProductName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProductName)
            @Html.ValidationMessageFor(model => model.ProductName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ProductCategory)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProductCategory)
            @Html.ValidationMessageFor(model => model.ProductCategory)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ProductDescription)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProductDescription)
            @Html.ValidationMessageFor(model => model.ProductDescription)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Test it out. Run your application, list all the products and click on Edit. You should get a window with the details of the Product you have clicked on. Our next step is to make our Edit work.

Before we create our Controller method which edits our product, we need to create the Edit method inside our business class which edits a Product instance. This code is shown underneath and this code might seem complicated for some of you. What I am doing is that I am getting the current Product from our database (line 8), attaching the existing product to our Entities instance (line 9) and then applying the new values on the existing Product (line 10). Finally I am saving the modified Product back to the database.

/// <summary>
 /// Edits a current product by getting the existing product and then applying the new values on the existing product.
 /// </summary>
 /// <param name="EditedProduct">Edited product.</param>
 public void EditProduct(Product EditedProduct)
 {
 Models.MVCBlogDBEntities entities = new MVCBlogDBEntities();
 Product ExistingProuct = entities.Products.SingleOrDefault(p => p.ProductId == EditedProduct.ProductId);
 entities.Products.Attach(ExistingProuct);
 entities.Products.ApplyCurrentValues(EditedProduct);
 entities.SaveChanges();
}

Let’s create the Edit controller which will act as our HttpPost method. This method will accept a Product instance and than call the Edit method inside our business class to edit the Product. Finally we redirect to our Product Index to list all the existing products. The product you have edited should now have the new values. This code is shown underneath.

[HttpPost]
 public ActionResult Edit(Models.Product EditedProduct)
 {
 Models.DBProducts dbproduct = new Models.DBProducts();
 dbproduct.EditProduct(EditedProduct);
 return RedirectToAction("Index");
}

So now what’s remaining is the Delete controller method which actually is the easiest one we will be having since we do not need to create a View for this. Let’s start by creating the method in our business class which actually deletes the product.

 /// <summary>
 /// Deletes an existing product.
 /// </summary>
 /// <param name="ProductId">Product id to be deleted.</param>
 public void DeleteProduct(Guid ProductId)
 {
 Models.MVCBlogDBEntities entities = new MVCBlogDBEntities();
Product ProductToDelete = this.GetProduct(ProductId);
 entities.Products.DeleteObject(ProductToDelete);
 entities.SaveChanges();
 }

In the above code I am first getting the existing product to be deleted (line 8) and then deleting the actual object from our database (line 9).

Now let’s create our Delete controller method which will accept an Id parameter which actually calls the newly created method. Basically this controller method is shown underneath. Make sure to call the parameter id because if not it will not work. In some future blog post I will also cover why this happens.

 public ActionResult Delete(Guid id)
 {
 Models.DBProducts dbproduct = new Models.DBProducts();
 dbproduct.DeleteProduct(id);
 return RedirectToAction("Index");
}

So that’s all for this blog. You should now have a View which actually lists all the products and then the user is able to Add/Edit and Deletes an existing product.
I hope you found this blog interesting and useful… CYA soon.