来自 Action 方法的 Return Json 在页面上打印 json 而不是在网格控件上显示

Return Json from Action method prints the json on page instead of showing on grid control

我正尝试按照 link 中的说明 运行 JQWidgets 的演示。但是当我 运行 演示时,我只是像这样在网页上打印 json。

这是我的 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();
        }
    }
}

这是DataHandler视图

@{
    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>

这里是 Employee 模型

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;
            }
        }
    }
}

您看到该屏幕是因为您直接调用了 DataHandler() 方法(通过 link 或浏览器地址栏)。该方法的目的是 return 一个 JsonResult 供您的 jqwidget 插件使用,您不应该导航到它。

DataHandler.cshtml 视图的名称更改为 Index.cshtml,然后导航到 HomeControllerIndex() 方法。然后该方法将 return 您显示的视图,这将依次调用您 DataHandler() 方法来 return 数据以填充网格。

要防止直接导航到该方法,您可以使用 [AjaxOnly] only 属性修饰 DataHandler() 方法。一个典型的例子看起来像

[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);
        }
    }
}

附带说明一下,您的 DataHandler() 并不是真正需要的,您可以在初始请求中传递模型并节省第二次调用服务器的额外开销。将 Index() 方法中的代码更改为

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

然后在视图中添加

@model IEnumerable<Employee>
...

然后更改脚本以使用您使用 localdata 数据选项

传递给视图的模型
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))
};