MarkAFarrugia

Freelance Web Development in Malta

By

Uploading Images in 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 :) .

The outcomes of this blog are to

  1. Discover how we can upload an image back to our server
  2. Understand when and how we can use IF conditions using Razor syntax
  3. Display a Product Image back in our View
  4. Understand how we can use the RedirectToAction and passing data back to out controller

The prerequisites of this blog are

  1. You should have a Products table which has a specific field of type Varchar which will store the image path
  2. You should have some understanding of LINQ To Entities
  3. You should have SQL Server Express installed. You can download it from here.
  4. You should have an Images and then Products subfolder in your project where we will be saving the uploaded image

In this blog I will be writing on how you can upload an Image back to a server using ASP.NET MVC. For those of you who are familiar with ASP.NET will find that the way this is done using ASP.NET MVC is somewhat different. In ASP.NET you would use the FileUpload control which takes care of most of the functionality.

So first things first. Let’s start by modifying our Edit Product View we have created in this blog. We will be adding an HTML form tag which basically is a form which posts back to a Controller action method which saves the image back to the server, and updates the relevant product with the image path. The Controller action method’s name is UploadProductImage and will accept a ProductId parameter. The underneath code snippet is the actual code which should be placed in our ASP.NET MVC View.

<form id="productimageuploadform" action="/Products/UploadProductImage" method="post" name="productimageuploadform" enctype="multipart/form-data">
  <input id="ProductId" type="hidden" name="ProductId" value="@Model.ProductId" />
 <input id="imguploadproductimage" title="Upload a product image" type="file" name="imguploadproductimage" />
 <input title="Upload image" type="submit" value="Upload" /></form>

Let me explain the above code. In the first line I am creating a form which posts back to the Products/UploadProductImage controller method. Note that a form which will upload an image should have the attribute enctype set to multipart/form-data. If this is not set the image will not be uploaded.

In the second line I am creating a hidden HTML field which stores the ProductId so that this will be passed back to our controller method. You will note that the Controller method has a single parameter also called ProductId. MVC will then map this hidden field value to the ProductId parameter inside the Edit Product controller method, since they have the same name. Recall that in this blog we created a Controller method which returns a single Product back to our Edit View. Thus I am using Razor syntax @Model.ProductId which basically returns the ProductId which is returned from our HttpGet Edit Product controller method.

In line 3 and 4 I am just creating an HTML input file control which basically will allow the user to select an image and a submit button which actually submits back to our Controller method.

Run your application and you should have a View as shown in Figure 1. Please note that this View is a continuation of the Product View we have created in this blog.

Product Upload Image View

Figure 1 – ASP.NET MVC which lets you upload a product image.

Let’s now create code for our UploadProductImage controller method, which the HTML form we have created posts to. This code is shown underneath. Basically in this code we are saving the image back to our server and then updating the existing Product with the image path on our server.

[HttpPost]
 public ActionResult UploadProductImage(Guid ProductId)
 {
 if (Request.Files.Count > 0)
 {
 try
 {
 if (Request.Files[0].ContentLength > 0)
 {
 HttpPostedFileBase postedFile = Request.Files[0];
 string filename = System.IO.Path.GetFileName(Request.Files[0].FileName);
 string strLocation = HttpContext.Server.MapPath("~/images/products");
 Request.Files[0].SaveAs(strLocation + @"\" + filename.Replace('+', '_'));
 Models.DBProducts products = new Models.DBProducts();
 Models.Product Product = products.GetProduct(ProductId);
 Product.ProductImagePath = @"\images\products\" + filename;
 products.EditProduct(Product);
 return RedirectToAction("Edit", new { id = ProductId });
 }
 }
 catch (FormatException ex)
 {
 return Content(ex.Message);
 }
 catch (Exception ex)
 {
 throw ex;
 }
 }
 return RedirectToAction("Edit", new { id = ProductId });
 }

So let me explain the code above. First of all note the method definition. The method accepts a parameter called ProductId which has the same name as our hidden field inside our HTMLform. You will be able to access the file uploaded using the Request.Files property.

On line 4 I am ensuring that there is at least one file and on line 8 I am ensuring that the file uploaded is not empty.

On line 10 I am getting the actual file uploaded as an HttpPostedFileBase class. I am then getting the filename of the file uploaded.

On line 12 I am getting the actual path where the image will be saved on the server. For those of you who do not know the Server.MapPath() basically returns the physical location on the server for a specific path. So for example, in our case we are getting the server physical path of the images/products folder. Remember that we need to transfer the file from the client pc to the server, and therefore we need to find the server physical location where the image will be saved. On line 13 we are then saving the image from the client to the server physical path using the SaveAs method. I am replacing the + sign with an _ since the + sign is not valid in a URL.

Then from line 15 to 17 I am saving the relative image path back to the database. So for example we might be saving /images/products/Image1.jpg back to our database.

On line 18 and on line 30 I am redirecting the user back to the Edit View and redisplaying the Edit Product MVC View. Note that I am passing the id parameter back to the controller. The Product should then be shown together with its new product image.

Finally let me give you part of the code to display an image on an ASP.NET MVC View. This code should be included in the ASP.NET MVC View which displays the product. I am not going to show you all the code which displays all the other Products fields, since this was covered in this blog. Rather I will only be showing the code which displays the image on our ASP.NET MVC View.

@if (!string.IsNullOrEmpty(Model.ProductImagePath))
 {
 <img src="@Model.ProductImagePath" alt="@Model.ProductDescription" title="@Model.ProductDescription" />
 }

In the above code there are some new things which I will explain. Note the IF statement using Razor syntax. Basically what I am doing is that if the Product has no image associated I am not displaying the img tag. Secondly, I am specifying the src of the Image as being the one which the ProductImagePath inside the Products table points to. Note that in these cases we append Razor code using the @ sign.

Run the application and you should end up with the an ASP.NET MVC View which resembles the one in Figure 2.

Figure 2 - Image uploaded and shown in ASP.NET MVC View

Figure 2 -Image uploaded and shown in ASP.NET MVC View

So I hope you found this blog post useful easy to follow. Till next time take care :) .

By

Examining the MVC View which displays data

In the previous blog post we saw how we can list data inside our views. However we did not dwell into the HTML markup which ASP.NET MVC creates when a list of items is displayed.

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

  1. How an ASP.NET MVC View to display data can look like
  2. Understand the HTML markup which is available to display records on an MVC View
The prerequisites for this blog are
  1. You should follow this blog to create a View which lists data back from a database

If you open the View which ASP.NET MVC created, which in our case is called Index and is located under the Views/Products folder you will find the underneath HTML markup.

@model IEnumerable

@{
 ViewBag.Title = "Index";
 Layout = "~/Views/Shared/_Layout.cshtml";
}</pre>
<h2>Index</h2>
<pre>
 @Html.ActionLink("Create New", "Create")</pre>
@foreach (var item in Model) {}
<table>
<tbody>
<tr>
<th>@Html.DisplayNameFor(model => model.ProductName)</th>
<th>@Html.DisplayNameFor(model => model.ProductCategory)</th>
<th>@Html.DisplayNameFor(model => model.ProductDescription)</th>
<th></th>
</tr>
<tr>
<td>@Html.DisplayFor(modelItem => item.ProductName)</td>
<td>@Html.DisplayFor(modelItem => item.ProductCategory)</td>
<td>@Html.DisplayFor(modelItem => item.ProductDescription)</td>
<td>@Html.ActionLink("Edit", "Edit", new { id=item.ProductId }) |
 @Html.ActionLink("Details", "Details", new { id=item.ProductId }) |
 @Html.ActionLink("Delete", "Delete", new { id=item.ProductId })</td>
</tr>
</tbody>
</table>
<pre>

From the above code you will soon realize that ASP.NET MVC is basically rendering all products as a table. Now let me explain some important constructs which are written in the above code.

From line number 1 you will deduce that this View accepts a list of Products. This would have been returned from the actual controller.

@model IEnumerable

In line number 11 you will find a special ASP.NET MVC construct which is @Html.ActionLink(“Create New”, “Create”). This basically creates a link which will take you to the Create Product’s controller method. The text displayed for the hyperlink will be Create New. This will basically take you to a page where you can create a new product.

   @Html.ActionLink("Create New", "Create")

At line number 16 you have another special MVC construct which is @Html.DisplayNameFor(model => model.ProductName) which basically displays a label for the ProductName field which belongs to the Products table.

    @Html.DisplayNameFor(model => model.ProductName)

At line number 30 a special construct @Html.DisplayFor(modelItem => item.ProductName) to display a specific input element related to the table’s field is shown. For example, if you have a String field then this construct will render as an HTML textbox, whilst if the field is a boolean then this will get rendered an HTML checkbox.

     @Html.DisplayFor(modelItem => item.ProductName)

At line number 39,40 and 41 you have 3 constructs which are very similar which will basically render as a hyperlink and will take you to the Edit, Details and Delete Product’s controller methods respectively. These controller methods will give the user the opportunity to Edit, View product details and Delete a specific product respectively.

       @Html.ActionLink("Edit", "Edit", new { id=item.ProductId }) |
       @Html.ActionLink("Details", "Details", new { id=item.ProductId }) |
       @Html.ActionLink("Delete", "Delete", new { id=item.ProductId })

So in this blog post I explained some special ASP.NET MVC helpers and how they can help you display data. I hope you found this blog post useful. In the next blog post we will be creating the controller method which will let us Edit, Create, View Details and Delete a specific product.

By

Creating our first ASP.NET MVC View

In this blog post I will be creating our first simple ASP.NET MVC View which will just display a Hello World message :) . At the end of this blog you should be able to

  1. Start understanding how ASP.NET URL rewriting works
  2. Understand how to pass messages between a Controller and a View
  3. Understand how Controllers should be named
  4. Understand the mapping between Controller and their respective Views
  5. Understand where Views should be stored

To create our first View we will first be creating a Controller method inside the HomeController. Before I create our first View it is good to understand how ASP.NET controllers link to Views by giving several examples.

The first thing to understand is that all Controller names need to end with the Controller name. For example in the sample MVC application there are 2 controllers which are the HomeController and AccountController, as shown in Figure 1. In these controllers there are several methods which link to ASP.NET MVC Views. For example, in the HomeController there are 3 controller methods which are Index, About and Contact as shown in Figure 2.

Figure 1 - Home and Account Controller

Figure 1 – Home and Account Controller

Figure 2 - HomeController Methods

Figure 2 – HomeController Methods

How are these Controller methods called? I will be giving several examples underneath of different URLs the user can type in order to call these Controller methods

  1. http://localhost/Home/Index – The Index Controller method inside the HomeController is called.
  2. http://localhost/Home – The Index Controller method inside the HomeController is called
  3. http://localhost/Home/About -  The About Controller method inside the HomeController is called.
  4. http://localhost/Home/Contact -  The Contact Controller method inside the HomeController is called.

First of all if you take a look at the above URLs you will immediately realize that the URLs to access ASP.NET MVC pages are totally different from calling ASP.NET pages. The above URLs are much better for Search Engine Optimization (SEO), and sometimes these type of URLs are called slugs.

Taking the example URL shown underneath you will note that the first part is the Controller name while the second part is the Controller method name. So in the example shown Home represents the Controller name (in fact there is a Controller named HomeController), while Index is the Controller method name (in fact there is a method called Index in the Home Controller. (Figure 3) (Figure 4)

Figure 3 - Naming structure inside controllers

Figure 3 – Naming structure inside controllers

Figure 5 - URL Structure

Figure 5 – URL Structure

Let’s now create our ASP.NET MVC 4 view. Create a controller method called Test inside the HomeController, as shown in Figure 5 and type the following code return View(); This code basically returns the matching View with this Controller

Figure 5 - Test method

Figure 5 – Test method

Let’s run our application and let’s try to access our Controller method by typing http://localhost/Home/Test. You will see that an exception as shown in Figure 6 will be returned. The reason for this exception is that ASP.NET MVC will try to search for the relevant ASP.NET MVC view which relates to the Controller method. This View which should be named Test.cshtml should be stored inside the VIEWS-HOME folder. If this is not found then ASP.NET MVC will show the exception shown in Figure 6. ASP.NET MVC will try to find this page in several other locations and after failing to find any matching pages an exception will be thrown.

Figure 6 - Exception when View not found

Figure 6 – Exception when View not found

So where should ASP.NET views should be stored? All ASP.NET MVC views are stored inside the VIEWS folder. The naming structure which ASP.NET MVC adopts is that the folder relates to the Controller name, while the page will be named according to the method name.

So taking into account the example shown in Figure 5, a page named Test.cshtml should be created inside the Home folder. In fact, as shown in Figure 7, you will note that there are 3 pages which are related to the 3 methods which have been automatically created by our sample application. These views are named Home.cshtml, About.cshtml and Contact.cshtml.

Figure 7 - Sample Views

Figure 7 – Sample Views

Let’s go back to our example. If we wish to create a new View which will serve as our Test page we should go inside the Test controller method, click the right mouse button and then click on ADD VIEW. Figure 8 shows how this should be done.

Figure 8 - Add View

Figure 8 – Add View

You will then have to select several options. For now we will not go into detail into what this page provides. You only have to make sure that you select the MasterPage which in our sample application is called _Layout.cshtml and is found under the Shared folder, as shown in Figure 9. A page will be created. Now if you type in the URL http://localhost/Home/Test you will see that the page correctly opens as shown in Figure 10.

Figure 9 - Add View options

Figure 9 – Add View options

Figure 10 - View correctly loads

Figure 10 – View correctly loads

Now let’s try to send a message back to our view. To do this we can use what so called the ViewBag which is used as a temporary storage which can then be passed and used by our ASP.NET MVC View.  The code shown in Figure 11 creates a ViewBag variable called Message and stores a Hello World message in this ViewBag variable. You can then display this message inside the View by using Razor syntax as shown in Figure 12. Note that when typing Razor code inside the View you need to preappend it with the @ sign.

Figure 11 - ViewBag

Figure 11 – ViewBag

Figure 12 - Razor inside View

Figure 12 – Razor inside View

Now run the application, type in http://localhost/Home/Test, and you see that the Hello World message is correctly displayed, as shown in Figure 13.

Figure 13 - View with message

Figure 13 – View with message

So enough for this blog…. I hope you found it useful.