Ajax and jQuery in ASP.NET MVC

Using jQuery and Ajax asynchronous calls can improve your web application’s performance dramatically. Ajax calls, request and retrieve only partial data giving the user a sense of a better interactive user interface experience. This post will show you how to use jQuery and retrieve data through Ajax calls. Ajax will target controller’s actions methods which in turn, will return a partial view or even JSON data (we will see JSON in later post, that’s for sure). If you aren’t familiar how actions can return partial views, you can read this post. So let’s start creating our MVC application.

Open Visual Studio and create a new ASP.NET MVC 4 Web Application (Internet Application) named “MvcAjaxApplication”, choosing the Basic option for template. We will build a web application where users can retrieve Product objects and manipulate them as well. All actions are going to be handled through Ajax calls. First of all, we need to create our Domain model so, go ahead and create a Product class inside the Models folder.

namespace MvcAjaxApplication.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public int UnitsInStock { get; set; }
    }
}

We won’t use mock Product objects, but instead we are going to store our products in a Microsoft SQL Server database. Log in to your SQL Server Management Studio and create a new database named “ProductsStore”. Right click the Tables folder and add a new Table with the following Columns. Save the new table and name it Products.

ajaxmvc5

Add some records for your Product objects. Feel free to add your own if you want.

ajaxmvc6

It’s time to connect our Domain Model with this database. We are going to use the LINQ to SQL perspective, so if you aren’t familiar with this please read this post. Add a reference to System.Data.Linq assembly if it hasn’t already exist. Change your Product class as follow.

using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace MvcAjaxApplication.Models
{
    [Table(Name="Products")]
    public class Product
    {
        [Column(IsPrimaryKey=true)]
        public int Id { get; set; }
        [Column]
        public string Name { get; set; }
        [Column]
        public string Description { get; set; }
        [Column]
        public decimal Price { get; set; }
        [Column]
        public int UnitsInStock { get; set; }
    }
}

Create a folder named “Infrustructure” and add a C# class file named “ProductsContext.cs” with a “Connections” class as follow. Paste the following code and make sure you change your Data Source respectively.

using MvcAjaxApplication.Models;
using System.Data.Linq;

namespace MvcAjaxApplication.Infrustructure
{
    public class Connections
    {
        public static string connection = "Data Source=developer-pc;Initial Catalog=ProductsStore;Integrated Security=True";
    }

Enough with the modeling, let’s test if we can access our database Products table. Create an Empty MVC “HomeController” controller in the controllers folder.

using MvcAjaxApplication.Infrustructure;
using MvcAjaxApplication.Models;
using System.Data.Linq;

namespace MvcAjaxApplication.Controllers
{
    public class HomeController : Controller
    {
        DataContext context;

        public HomeController()
        {
            this.context = new DataContext(Connections.connection);
        }

        public ActionResult Index()
        {
            Product[] products = context.GetTable().ToArray();
            return View(products);
        }

    }
}

Right click in your Index action method and create a new View, named Index with a strongly typed of IEnumerable<Product> type. Paste the following code, build your application and run it. You should see all your database products.

@using MvcAjaxApplication.Models
@model IEnumerable<Product>

@{
    ViewBag.Title = "Products";
}

<h2>My Products</h2>

<table>
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Description</th>
        <th>Price</th>
        <th>UnitsInStock</th>
    </tr>
    @foreach (Product p in Model)
    {
        <tr>
            <td>@p.Id</td>
            <td>@p.Name</td>
            <td>@p.Description</td>
            <td>@p.Price</td>
            <td>@p.UnitsInStock</td>
        </tr>
    }
</table>

ajaxmvc7

Ok, it’s time to create some Ajax calls. Well, the idea is this. We will have some static HTML markup in the Index View, an empty div element and a button. When the user clicks the button, an Ajax call will invoke a GetProducts action method which in turn, will return a partial view. We ‘ll put the contents of this partial view in the empty div element. Let’s do it. Create a GetProducts action method in the HomeController. Also, make sure you change the Index action’s code later.

public class HomeController : Controller
    {
        DataContext context;

        public HomeController()
        {
            this.context = new DataContext(Connections.connection);
        }

        public ActionResult Index()
        {
            
            return View();
        }

        public PartialViewResult GetProducts()
        {
            Product[] products = context.GetTable<Product>().ToArray();

            return PartialView(products);
        }
    }

Right click inside the GetProducts action and add a new Partial View. Fill the Window as follow.

ajaxmvc8

Change the new Partial View’s contents. You will notice that we pasted almost the same contents with the Index View.

@using MvcAjaxApplication.Models
@model IEnumerable<Product>

<table>
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Description</th>
        <th>Price</th>
        <th>UnitsInStock</th>
    </tr>
    @foreach (Product p in Model)
    {
        <tr>
            <td>@p.Id</td>
            <td>@p.Name</td>
            <td>@p.Description</td>
            <td>@p.Price</td>
            <td>@p.UnitsInStock</td>
        </tr>
    }
</table>

Change Index View’s contents as follow.

@using MvcAjaxApplication.Models

@{
    ViewBag.Title = "Products";
}

<div style="width:600px; margin-left:auto; margin-right:auto">
    <div style="background-color: lightgray">
        <h2>My Products</h2>
    </div>
    <p>Click the button to Get Products with an Ajax call</p>
    <input id="btnAjax" name="btnAjax" type="button" value="Get Products" />
    <div id="products" style="background-color:lightskyblue"></div>
</div>

@section Scripts {
<script>
    $('#btnAjax').click(function () {
        $.ajax({
            url: '/Home/GetProducts',
            contentType: 'application/html; charset=utf-8',
            type: 'GET',
            dataType: 'html'

        })
        .success(function (result) {
            $('#products').html(result);
        })
        .error(function (xhr, status) {
            alert(status);
        })
    });
</script>
    }

We have bound the “btnAjax” button’s click event to an Ajax call. This call targets the Home controller’s GetProducts action (url parameter). If the call is successful we simply place the returned html into the “products” div. So simple. Run your application and click the button.

ajaxmvc9

Click the button and you ‘ll get:

ajaxmvc10

Now let’s try to update some of our products. I ‘ll try to keep the example simple, so I will just add two textboxes and a button bellow the code of our Index View. I will place this code in a div with a display:none. This means that when you run your application you won’t see it, but when you click the button to retrieve your products, you will. We ‘ll try to change a product’s Price value. This way, when our products are retrieved, we will be able to fill the first textbox with the product’s Id and the second one with the new Price value. Add the following code to the Index View.

@using MvcAjaxApplication.Models

@{
    ViewBag.Title = "Products";
}

<div style="width: 600px; margin-left: auto; margin-right: auto">
    <div style="background-color: lightgray">
        <h2>My Products</h2>
    </div>
    <p>Click the button to Get Products with an Ajax call</p>
    <input id="btnAjax" name="btnAjax" type="button" value="Get Products" />
    <div id="products" style="background-color: lightskyblue"></div>
</div>

<div id="changePriceDiv" style="display: none">
    <hr />
    <table>
        <tr>
            <th>Product ID</th>
            <th>New Price</th>
        </tr>
        <tr>
            <td>
                <input id="txtId" name="txtId" type="text" /></td>
            <td>
                <input id="txtPrice" name="txtPrice" type="text" /></td>
        </tr>
    </table>
    <input id="btnChangePrice" name="btnChangePrice" type="button" value="Change Price" />
</div>

You need to show this div, when your retrieve your products. Change your success Ajax callback, like this.

$('#btnAjax').click(function ajaxCall() {
            $.ajax({
                url: '/Home/GetProducts',
                contentType: 'application/html; charset=utf-8',
                type: 'GET',
                dataType: 'html'

            })
            .success(function (result) {
                $('#products').html(result);
                $('#changePriceDiv').show().appendTo($('#products'));
            })
            .error(function (xhr, status) {
                alert(status);
            })
        }

Now if you click the GetProducts button you will a get this result.

ajaxmvc11

We need to add a new action in our HomeController, to update a product’s price. The action will get an int parameter for the product’s id and a decimal parameter for the new Price . Then, using LINQ to SQL will change the respective product’s price, save it in database and finally, it will return the same partial View as the GetProducts action. The user though, is going to see only the new product’s price changed in the user interface.

public PartialViewResult ChangeProductPrice(int id, decimal newPrice)
        {
            IList<Product> products = context.GetTable<Product>().ToArray();
            Product product = products.Where(p => p.Id == id).Single();
            product.Price = newPrice;
            context.SubmitChanges();
            return PartialView("GetProducts", products);
        }

The last thing we need to do, is to bind the “btnChangePrice” button’s click event to an Ajax call targeting the ChangeProductPrice action. Add the following code to the Index View. Pay attention on the data attribute and how is used to sent your Id and New Price values.

<script>
        $('#btnAjax').click(function ajaxCall() {
            $.ajax({
                url: '/Home/GetProducts',
                contentType: 'application/html; charset=utf-8',
                type: 'GET',
                dataType: 'html'

            })
            .success(function (result) {
                $('#products').html(result);
                $('#changePriceDiv').show().appendTo($('#products'));
            })
            .error(function (xhr, status) {
                alert(status);
            })
        }
        );


        $('#btnChangePrice').click(function () {
            var idVal = $('#txtId').val();
            var newPriceVal = $('#txtPrice').val();
            $.ajax({
                url: '/Home/ChangeProductPrice',
                contentType: 'application/html; charset=utf-8',
                data: {id : idVal, newPrice : newPriceVal },
                type: 'GET',
                dataType: 'html'

            })
            .success(function (result) {
                $('#products').html(result);
            })
            .error(function (xhr, status) {
                alert(status);
            })
        });
    </script>

That’s it. Build and run your application. Click and retrieve your products. Select an Id and enter a new Price (We didn’t write any validation code, so make sure you enter valid values).

ajaxmvc12

ajaxmvc13

It’s very important to know how to use Ajax and retrieve data in your ASP.NET MVC applications. Another approach which we are going to see in later post, is to retrieve JSON data from your MVC actions through Ajax. I hope you enjoyed the post. Download the MvcAjaxApplication project we have created from here.

In case you find my blog’s content interesting, register your email to receive notifications of new posts and follow chsakell’s Blog on its Facebook or Twitter accounts.

Facebook Twitter
.NET Web Application Development by Chris S.
facebook twitter-small


Categories: ASP.NET

Tags: , ,

40 replies

  1. Thank you. This walkthrough was really helpful. Not only is it a complete example using MVC, I really feel I understand Ajax more after going through it.

  2. Thank you very much, I’m glad I helped..

  3. Usually I can’t understand posting on blogs and forums, however want to express that this write-up incredibly pressured me to consider and also apply it! Your own way of writing continues to be astonished me personally. Cheers, pretty excellent post.

  4. Thanks, I struggled a lot but your article helped me a lot. Srikant pandey

  5. This article is really very helpful.. Thanks

  6. Thank you, this was a great.

  7. It’s hard to find your page in google. I found it on 22
    spot, you should build quality backlinks , it will help you to increase traffic.
    I know how to help you, just type in google – k2 seo tips

  8. When you said :
    “Create a folder named “Infrustructure” and add a class named “ProductsContext” “,
    did you meant class Connections?
    I don’t see any class “ProductsContext”. Thanks for the great lessons.

  9. Thanks, it’s very helpful.

    Uh, can you add a loading animation (gif) when the data loaded pls?

    Thanks

  10. Very helpful your post… Thanks

  11. How do I post code here? Can I just paste it in a comment since I want to paste the entire Index.cshtml? I wanted to respond to a question about how to include a loading panel in your excellent example. You are very good at writing and the material is top class.

  12. Please do not use the code I pasted in my above comment since the html part has not been shown correctly. You can simply go to this link to get the modified files: https://onedrive.live.com/redir?resid=A92AE4EE378A11EB%21303. Make sure to right-click the item for downloading it.

    • Sunil I removed the Html code. Indeed it was a little bit confusing. Readers can download you files from the link you provided. Thanks a lot again.

      • Hi Christos, This is my post on displaying loading panel. Please remove the previous post on this.

        Here is how I was able to show an animated gif in the excellent AJAX sample provided by Christos.

        For loading image to show, there are 2 important points you must keep in mind.

        1.The AJAX request must have this setting ‘async: true’ else the browser will freeze while the ajax request is made and your loading image will not render as expected.
        2.For GET type of AJAX requests, make sure to have this setting ‘cache:false’, else after the first ajax request subsequent ones will not make a server trip but just use the browser cache to get the ajax response in a matter of a few milliseconds, and this super-fast response will never result in the loading image from showing.

        You can display a loading image or just a loading message. For loading image you must get an animated gif of 32 X 32 ( if you get larger size then change the width/height of img element in code below). I used this url to generate a loading image: http://preloaders.net/en/circular. If you want to display a loading message only then use the commented ‘loading’ CSS in code below. You can download a sample loading image from https://onedrive.live.com/redir?resid=A92AE4EE378A11EB%21304. Make sure you create Images folder under Content where you can place this loading image.

        Another useful feature in Index view, is a delay interval for loading panel. There is a JavaScript variable set like this in Index.cshtml: “var loaderDelayTime = 300;”. This is used so users can make their loading image less obtrusive for very fast ajax responses, and it decides how many milliseconds to wait before displaying a loading panel. In my view for fast responses like almost instant, there is no point in showing a loading panel.

        You can simulate a long response by sleeping the current thread in HomeController.

        Only changes in Index.cshtml should be enough to implement loading in this example. But I have also made some appearance changes in GetProducts.cshtml and added Thread.Sleep code to HomeController to show a loading panel. You can download these code changes from: https://onedrive.live.com/?cid=a92ae4ee378a11eb&id=A92AE4EE378A11EB!303.

  13. I really thank you for this article. I was needing a good example about Ajax calls in a ASP.NET MVC application =)

  14. you re so kind..
    thank you for your post..

  15. I liked the way you presented the tutorial.

  16. thank you, this was very very helpful

  17. thank you, this was very very helpful

  18. Thank You Very much..

    Its a very lucid and awesome explanation.

    Thanks again ! 🙂

  19. Unquestionably imagine that that you stated.
    Your favorite reason appeared to be on the web the easiest factor to have in mind of.
    I say to you, I definitely get annoyed while other people consider concerns that they plainly
    don’t recognize about. You controlled to hit the nail upon the highest and defined out the whole
    thing with no need side-effects , other people could take a signal.

    Will likely be again to get more. Thank you

  20. Hi,
    Thanks for the wonderful writing. Please help me on below error:

    The type arguments for method ‘System.Data.Linq.DataContext.GetTable()’ cannot be inferred from the usage. Try specifying the type arguments explicitly.

    In this line: Product[ ] products = context.GetTable().ToArray();

    Thanks.

  21. its very clear work. this wl very helpful to beginner

  22. Hi Chris,

    How can we display the ChangePriceDiv after success on #btnChangePrice’).click function ?
    I tried as below but it is not working:

     $("#btnCP").click(function () {
                var idVal = $("#txtId").val();
                var np = $("#txtPrice").val();
                $.ajax({
                    url: '/Home/ChangeProductPrice',
                    contentType: 'application/html;charset=utf-8',
                    data: { id: idVal, newPrice: np },
                    type: 'GET',
                    dataType: 'html'
                })
                .success(function (result) {
                    $('#products').html(result);
                    $("#ChangePriceDiv").show().appendTo($("#products"));
                    //alert("Modified!!")
                })
                .error(function (xhr, status) {
                    alert(status);
                });
            });
    
    • I guess you don’t want to loose the changePriceDiv div. Change the Index.cshtml as follow and you ‘ll be fine.

      @using MvcAjaxApplication.Models
      
      @{
          ViewBag.Title = "Products";
      }
      
      <div style="width: 600px; margin-left: auto; margin-right: auto">
          <div style="background-color: lightgray">
              <h2>My Products</h2>
          </div>
          <p>Click the button to Get Products with an Ajax call</p>
          <input id="btnAjax" name="btnAjax" type="button" value="Get Products" />
          <div id="products" style="background-color: lightskyblue">
          </div>
          <div id="changePriceDiv" style="display: none; background-color: lightskyblue;">
              <hr />
              <table>
                  <tr>
                      <th>Product ID</th>
                      <th>New Price</th>
                  </tr>
                  <tr>
                      <td>
                          <input id="txtId" name="txtId" type="text" />
                      </td>
                      <td>
                          <input id="txtPrice" name="txtPrice" type="text" />
                      </td>
                  </tr>
              </table>
              <input id="btnChangePrice" name="btnChangePrice" type="button" value="Change Price" />
          </div>
      
      </div>
      
      
      @section Scripts {
          <script>
              $('#btnAjax').click(function ajaxCall() {
                  $.ajax({
                      url: '/Home/GetProducts',
                      contentType: 'application/html; charset=utf-8',
                      type: 'GET',
                      dataType: 'html'
      
                  })
                  .success(function (result) {
                      $('#products').html(result);
                      $('#changePriceDiv').show();
                  })
                  .error(function (xhr, status) {
                      alert(status);
                  })
              }
              );
      
      
              $('#btnChangePrice').click(function () {
                  var idVal = $('#txtId').val();
                  var newPriceVal = $('#txtPrice').val();
                  $.ajax({
                      url: '/Home/ChangeProductPrice',
                      contentType: 'application/html; charset=utf-8',
                      data: { id: idVal, newPrice: newPriceVal },
                      type: 'GET',
                      dataType: 'html'
      
                  })
                  .success(function (result) {
                      $('#products').html(result);
                  })
                  .error(function (xhr, status) {
                      alert(status);
                  })
              });
          </script>
      }
      
  23. hey thanks this was very easy to understand…but i dont know y its not working for me, i downloaded your code its working with my database but in my project it does not work. when i removed $(‘#btnAjax”).click event, the list from my db appears.

  24. Thank You for your good article.

  25. the download file not there anymore

Trackbacks

  1. Unobtrusive Ajax in ASP.NET MVC | chsakell's Blog
  2. Comment on Ajax and jQuery in ASP.NET MVC by Dragan Došen

Leave a reply to Sunil Cancel reply