-1

I am trying to run the demo of JQWidgets by following the instructions in this link. But when I run the demo, I simply get the json printed on the webpage like this.

enter image description here

Here is my HomeController.cs

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

namespace JQWidgetGrids.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();
        }

        public ActionResult DataHandler()
        {
            List<Employee> employees = EmployeesRepository.GetEmployees();

            return Json(new
            {
                employees
            },
            JsonRequestBehavior.AllowGet);
        }

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

Here is the DataHandler view

@{
    ViewBag.Title = "DataHandler";
}

<title><asp:ContentPlaceHolder ID="TitleContent" /></title>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="~/Content/jqx.base.css" type="text/css" />
<script type="text/javascript" src="~/Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="~/Scripts/jqxcore.js"></script>
<script type="text/javascript" src="~/Scripts/jqxdata.js"></script>
<script type="text/javascript" src="~/Scripts/jqxbuttons.js"></script>
<script type="text/javascript" src="~/Scripts/jqxscrollbar.js"></script>
<script type="text/javascript" src="~/Scripts/jqxmenu.js"></script>
<script type="text/javascript" src="~/Scripts/jqxgrid.js"></script>
<script type="text/javascript" src="~/Scripts/jqxgrid.selection.js"></script>

<h2>DataHandler</h2>

<script type="text/javascript">
    $(document).ready(function () {
        var source =
          {
              url: "Home/DataHandler",
              datatype: "json",
              datafields: [{ name: "FirstName" }, { name: "LastName" }, { name: "Product" }, { name: "Price", type: "float" }, { name: "Quantity", type: "int" }, { name: "Total", type: "float" }]
          };

        var dataAdapter = new $.jqx.dataAdapter(source);

        $("#jqxgrid").jqxGrid(
          {
              source: dataAdapter,
              columns: [
                { text: 'First Name', dataField: 'FirstName', width: 100 },
                { text: 'Last Name', dataField: 'LastName', width: 100 },
                { text: 'Product', dataField: 'Product', width: 180 },
                { text: 'Quantity', dataField: 'Quantity', width: 80, cellsalign: 'right' },
                { text: 'Unit Price', dataField: 'Price', width: 90, cellsalign: 'right', cellsformat: 'c2' },
                { text: 'Total', dataField: 'Total', cellsalign: 'right', minwidth: 100, cellsformat: 'c2' }
              ]
          });
    });
</script>
<div id="jqxgrid"></div>

And here the Employee Model

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

namespace JQWidgetGrids.Models
{
    public class EmployeesRepository
    {
        public static List<Employee> GetEmployees()
        {
            List<Employee> employees = new List<Employee>();

            string[] firstNames = new string[] { "Andrew", "Nancy", "Shelley", "Regina", "Yoshi", "Antoni", "Mayumi", "Ian", "Peter", "Lars", "Petra", "Martin", "Sven", "Elio", "Beate", "Cheryl", "Michael", "Guylene" };
            string[] lastNames = new string[] { "Fuller", "Davolio", "Burke", "Murphy", "Nagase", "Saavedra", "Ohno", "Devling", "Wilson", "Peterson", "Winkler", "Bein", "Petersen", "Rossi", "Vileid", "Saylor", "Bjorn", "Nodier" };
            string[] productNames = new string[] { "Black Tea", "Green Tea", "Caffe Espresso", "Doubleshot Espresso", "Caffe Latte", "White Chocolate Mocha", "Cramel Latte", "Caffe Americano", "Cappuccino", "Espresso Truffle", "Espresso con Panna", "Peppermint Mocha Twist" };
            string[] priceValues = new string[] { "2.25", "1.5", "3.0", "3.3", "4.5", "3.6", "3.8", "2.5", "5.0", "1.75", "3.25", "4.0" };
            Random random = new Random();

            for (var i = 0; i < 100; i++)
            {
                Employee employee = new Employee();

                int productindex = random.Next(productNames.Length);
                float price = float.Parse(priceValues[productindex]);
                int quantity = 1 + random.Next(10);
                employee.FirstName = firstNames[random.Next(firstNames.Length)];
                employee.LastName = firstNames[random.Next(lastNames.Length)];
                employee.Price = price;
                employee.Quantity = quantity;
                employee.Product = productNames[productindex];
                employees.Add(employee);
            }
            return employees;
        }
    }

    public class Employee
    {
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Product { get; set; }
        public double Price { get; set; }
        public int Quantity { get; set; }
        public double Total
        {
            get
            {
                return this.Price * this.Quantity;
            }
        }
    }
}
WAQ
  • 2,556
  • 6
  • 45
  • 86
  • Firstly, it sounds like you're redirecting the browser to the JSON response instead of dealing with it in your AJAX code. Secondly, how are you expecting anyone to help you without showing the relevant code? – Rory McCrossan Aug 23 '17 at 10:41
  • Your method returns a JSON list instead of `ActionResult.View()` – Lab Lab Aug 23 '17 at 10:44
  • @RoryMcCrossan Im I should have put that in the first place.. Just now I have added the relevant view – WAQ Aug 23 '17 at 10:44
  • @LabLab I was following the demo (from the link above) and thats what it says. Can you correct if thats not right? – WAQ Aug 23 '17 at 10:51
  • 1
    @WAQ - ignore that comment from LabLab - you are correctly returning a `JsonResult` –  Aug 23 '17 at 10:53
  • @WAQ, in that article were used `ActionResult`, but in your code I can see `JsonResult` – Lab Lab Aug 23 '17 at 10:56
  • @LabLab I have tried both JsonResult and ActionResult. But yields the same result.. – WAQ Aug 23 '17 at 10:59
  • @WAQ you must have an ajax method, which will be receiving this json data and then will be appending it to the table. – Lab Lab Aug 23 '17 at 11:06
  • @LabLab can you please provide a link which can help me write such a ajax? – WAQ Aug 23 '17 at 11:08
  • 1
    @WAQ, Please ignore everything from LabLab. They clearly do not understand what your doing or the plugin your using. The code you have shown is fine. Its code that you have not shown that is causing the issue. That could only be happening if somewhere you clicking on a link (or redirecting via javascript) to your `DataHandler()` method. –  Aug 23 '17 at 11:41
  • Start by showing the controller method that generates that view. –  Aug 23 '17 at 11:45
  • @StephenMuecke I have edited the question and have put every single detail that seems relevant to me :) – WAQ Aug 23 '17 at 12:39
  • 1
    Well for a start that make no sense. Your view is named `DataHandler.cshtml` which means it would only be called if you navigated to your `DataHandler` method (but that method returns your json data). That view needs to be your `Index.cshtml` view. –  Aug 23 '17 at 12:42
  • 1
    I assume what your really doing is navigating to your `DataHandler()` method (either via a link or by typing it in the address bar - which would display that image, because that is what that method returns. –  Aug 23 '17 at 12:44
  • 1
    And I would recommend either marking the `DataHandler` method with `[HttpPost] ` (but not sure if that will work with your plugin), or you decorate it with an `[AjaxOnly]` attribute (refer [this answer](https://stackoverflow.com/questions/6558758/is-there-any-attribute-relating-to-ajax-to-be-set-for-asp-net-mvc-controller-act)) so you cannot navigate to it directly –  Aug 23 '17 at 12:46
  • @StephenMuecke this indeed helped and I was doing it the wrong way. please put this as an answer so that I can mark it as accepted. – WAQ Aug 23 '17 at 13:54

1 Answers1

1

Your seeing that screen because you calling your DataHandler() method directly (via a link or the browser address bar). That methods purpose is to return a JsonResult for use by your jqwidget plugin and you should not be navigating to it.

Change the name of your DataHandler.cshtml view to Index.cshtml and then navigate to the Index() method of HomeController. That method will then return the view you have shown, which will in turn call you DataHandler() method to return the data to populate the grid.

To prevent navigating directly to that method, you can decorate the DataHandler() method with a [AjaxOnly] only attribute. A typical example looks like

[AttributeUsage(AttributeTargets.Method)]
public class AjaxOnlyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.HttpContext.Response.StatusCode = 404;
            filterContext.Result = new HttpNotFoundResult();
        }
        else
        {
            base.OnActionExecuting(filterContext);
        }
    }
}

As a side note, your DataHandler() is not really required, and you can just pass the model in the initial request and save the extra overhead of making a 2nd call back to the server. Change the code in the Index() method to

public ActionResult DataHandler()
{
    List<Employee> model = EmployeesRepository.GetEmployees();
    return View(model );
}

then in the view, add

@model IEnumerable<Employee>
...

and then change the script to use the model you have passed to the view using the localdata data option

var source = {
    datatype: "json",
    datafields: [{ name: "FirstName" }, { name: "LastName" }, { name: "Product" }, { name: "Price", type: "float" }, { name: "Quantity", type: "int" }, { name: "Total", type: "float" }]
    localdata: @Html.Raw(Json.Encode(Model))
};