Retrieve JSON data from MVC Controllers in ASP.NET MVC

Using unobtrusive AJAX in your MVC web applications can boost system’s performance. We have seen in previous post how to use unobtrusive AJAX to retrieve only partial views instead of full page requests, in ASP.NET MVC Framework. While being a good approach to use Ajax in order to retrieve only partial views, you may have noticed that your controllers send back your data requested along with the HTML fragments. Remember? (screenshot from previous post)

ajaxunobtrusive4

In order to overcome this, we can request only the specific object data we want and let the client’s browser render the respective HTML fragments. The requested data will have to be in JavaScript Object Notation (JSON) format, which is a language-independent way of expressing data. We won’t create a new project but instead, we will continue to add code in the previous post. If you haven’t read it yet, please take a look at it or just make sure you download the project we had created. Open the solution in Visual Studio and change the ProductController.cs file to the following.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using MVCUnobtrusiveAjax.Models;

namespace MVCUnobtrusiveAjax.Controllers
{
    public class ProductController : Controller
    {
        private Product[] products = {
                                         new Product { 
                                             ProductId = 1, Name = "Audi A3",
                                             Description = "New Audi A3", Category = Category.Car,
                                             Price = 25000
                                         },
                                         new Product { 
                                             ProductId = 2, Name = "VW Golf",
                                             Description = "New VW Golf", Category = Category.Car,
                                             Price = 22000
                                         },
                                         new Product { 
                                             ProductId = 3, Name = "Boing 747",
                                             Description = "The new Boing airplane", Category = Category.Airplane,
                                             Price = 2000000
                                         },
                                         new Product { 
                                             ProductId = 4, Name = "Boing 747",
                                             Description = "The new Boing airplane", Category = Category.Airplane,
                                             Price = 2000000
                                         },
                                         new Product { 
                                             ProductId = 5, Name = "Yamaha 250",
                                             Description = "Yamaha's new motorcycle", Category = Category.Motorcycle,
                                             Price = 5000
                                         },
                                         new Product { 
                                             ProductId = 6, Name = "honda 750",
                                             Description = "Honda's new motorcycle", Category = Category.Motorcycle,
                                             Price = 7000
                                         }

                                     };

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

        private IEnumerable<Product> GetData(string selectedCategory)
        {
            IEnumerable<Product> data = products;
            if (selectedCategory != "All")
            {
                Category selected = (Category)Enum.Parse(typeof(Category), selectedCategory);
                data = products.Where(p => p.Category == selected);
            }
            return data;
        }

        public JsonResult GetProductDataJson(string selectedCategory = "All")
        {
            IEnumerable<Product> data = GetData(selectedCategory);
            return Json(data, JsonRequestBehavior.AllowGet);
        }
        public PartialViewResult GetProductData(string selectedCategory = "All")
        {
            return PartialView(GetData(selectedCategory ));
        }

        public ActionResult GetProducts(string selectedCategory = "All")
        {
            return View((object)selectedCategory);
        }

    }
}

We have created a GetData private method to get Product objects based on a selected category, passed as parameter to that function. The most important action method we added is the GetProductDataJson method, which returns a type of JsonResult object, something that tells the view engine to return JSON data to the client. Pay attention to this line of code:

return Json(data, JsonRequestBehavior.AllowGet);

You need to tell the MVC Framework to respond to GET requests, cause by default JSON data will only be sent in response to POST requests. The GetProductData action method renders partial view results, in the way we have seen in previous post.

Last thing we need to do, is to change the way the onSuccess Ajax call event works. Change the GetProducts.cshtml file as follows.

@using MVCUnobtrusiveAjax.Models
@model string
@{
    ViewBag.Title = "Get Products";
    AjaxOptions ajaxOptions = new AjaxOptions
    {
        UpdateTargetId = "productsTable"
    };
}

<script type="text/javascript">
    function processData(data) {
        var target = $("#productsTable");
        target.empty();
        for (var i = 0; i < data.length; i++) {
            var product = data[i];
            target.append("<tr><td>" + product.ProductId + "</td><td>"
            + product.Name + "</td><td>" + product.Description + "</td><td>"
            + product.Category + "</td><td>" + product.Price + "</td></tr>");
        }
    }
</script>

<h2>Get Products</h2>

<div id="loadingProducts" style="background-color: cadetblue; display: none">
    <p>Loading Products...</p>
</div>

<table style="background-color: lightcoral">
    <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Description</th>
            <th>Category</th>
            <th>Price</th>
        </tr>
    </thead>
    <tbody id="productsTable">
        @Html.Action("GetProductData", new { selectedCategory = Model })
    </tbody>
</table>
<hr />

@using (Ajax.BeginForm(ajaxOptions))
{
    <div>
        @Html.DropDownList("selectedCategory", new SelectList(
            new[] { "All" }.Concat(Enum.GetNames(typeof(Category)))))
        <button type="submit">Submit</button>
    </div>
}

<div>
    @foreach (string category in Enum.GetNames(typeof(Category)))
    {
        <div class="ajaxLink">
            @Ajax.ActionLink(category, "GetProducts",
                new { selectedCategory = category },
                new AjaxOptions { 
                Url = Url.Action("GetProductDataJson", new {selectedCategory = category}),
                OnSuccess = "processData"
                })
        </div>
    }
</div>

We added a script function processData to fill the productTable table as long as the JSON data have been retrieved. We bind this JavaScript method only in the Ajax ActionLinks in lines 56-66 through the OnSuccess = “processData” declaration. Line 41 will render the partial view through the GetProductData action method when you press the Submit button. So in the same page, we use two different ways to retrieve data with AJAX. One that renders partial views and another that returns JSON data that have to be manipulated by a script on client’s side. Build your application and run it. I need to show you something interesting. Select Car and click the “Submit” button. This will render the partial view and will display all Car objects. The category enum field has been rendered correctly.

ajaxjson_1

Now try to retrieve Car objects or other if you want, but clicking one of the links this time. I have clicked the Car link. Take a look at the Category field now and how JSON data have been retrieved.

ajaxjson_2

This problem occurs due to JSON’s default Encoding. To solve the problem, you need to tell the action method that returns the JSON data, exactly what type of object the client expects to get. Change the GetProductDataJson action method in the ProductController as follow.

public JsonResult GetProductDataJson(string selectedCategory = "All")
        {
                var data = GetData(selectedCategory).Select(p => new {
                ProductId = p.ProductId,
                Name = p.Name,
                Description = p.Description,
                Price = p.Price,
                Category = Enum.GetName(typeof(Category), p.Category)
                });
            return Json(data, JsonRequestBehavior.AllowGet);
        }

Build and run your solution again. Click an AJAX link like you did before.

ajaxjson_3

That’s it, we have shown how to get and manipulate JSON data retrieved from your MVC controllers. When it comes to JSON another concept may popup in your mind: MVC WebApi. We are going to see how WebApi approach works in a later post. You can download the project we created in this post from here. I hope you enjoyed the post.

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
Advertisements


Categories: ASP.NET

Tags: , ,

10 replies

  1. excellent, good contribution

  2. excellent example – download source code helped a lot!

  3. Thank you for helping

  4. Nice post. I specially liked the usage of submit and display of content on same page. Kudos!

Trackbacks

  1. Retrieve JSON data from MVC Controllers in ASP.NET MVC | skpachauri

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Chara Plessa

The purpose of this blog is to broaden my education, promote experimentation and enhance my professional development. Albert Einstein once said that “If you can’t explain it simply, you don’t understand it well enough” and I strongly believe him!

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Kumikoro

A Front End Developer's Blog

Muhammad Hassan

Full Stack Developer | ASP.NET | MVC | WebAPI | Advanced Javascript | AngularJS | Angular2 | C# | ES6 | SQL | TypeScript | HTML5 | NodeJS, MS candidate @LUMS, Grad & EX-Adjunct Faculty @NUCES-FAST, seasonal blogger & open-source contributor. Seattle, WA.

Software Engineering

Web development

IEvangelist

.NET, ASP.NET, C#, MVC, TypeScript, AngularJS

leastprivilege.com

Dominick Baier on Identity & Access Control

Happy DotNetting

In Love with Technology

Knoldus

Knols of experience to your advantage

knowshnet

Search - Read - Request - Share

Rahul's space

Learn, Share and Grow with me !

Dhananjay Kumar

Developer Evangelist @Infragistics | MVP @Microsoft |

SQL Authority with Pinal Dave

SQL Server Performance Tuning Expert

Conficient Blog

Random bits of tech from @conficient

Code! Code! Code!

SOLID & KISS

Code Wala

Designing and coding

Microsoft Mentalist

A way to start with Microsoft Technologies

Tony Sneed's Blog

A glimpse into the lives of Tony & Zuzana Sneed

Sriramjithendra Nidumolu

Personal Notes of Sriramjithendra

%d bloggers like this: