MarkAFarrugia

Freelance Web Development in Malta

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.