ASP.Net MVC 3 JQGrid

在阅读了JQGrid控件之后,我决定在我的一个ASP.Net MVC 3 Web应用程序中使用它。

首先,我按照Phil Haacks教程http://haacked.com/archive/2009/04/14/using-jquery-grid-with-asp.net-mvc.aspx这一切都很好。 然后我尝试在我的应用程序中实现类似的东西,唯一的区别是,我使用Linq To Entities。

我的View页面导入了所有的css和Jquery类,然后我有我的JavaScript函数和保存数据的表

 jQuery(document).ready(function () { jQuery("#list").jqGrid({ url: '/Home/LinqGridData/', datatype: 'json', mtype: 'GET', colNames: ['equipmentID', 'categoryTitle', 'title'], colModel: [ { name: 'equipmentID', index: 'equipmentID', width: 40, align: 'left' }, { name: 'categoryTitle', index: 'categoryTitle', width: 40, align: 'left' }, { name: 'title', index: 'title', width: 200, align: 'left'}], pager: jQuery('#pager'), width: 660, height: 'auto', rowNum: 10, rowList: [5, 10, 20, 50], sortname: 'Id', sortorder: "desc", viewrecords: true, imgpath: '/scripts/themes/coffee/images', caption: 'My first grid' }); }); 

 

My Grid Data

然后在我的控制器中,我有以下方法,假设返回Json数据

 public ActionResult LinqGridData(string sidx, string sord, int page, int rows) { AssetEntities context = new AssetEntities(); var query = from e in context.Equipments select e; var count = query.Count(); var result = new { total = 1, page = page, records = count, rows = (from e in query select new { id = e.equipmentID, cell = new string[] { e.equipmentID.ToString(), e.Category.categoryTitle, e.Department.title } }).ToArray() }; return Json(result, JsonRequestBehavior.AllowGet); } 

当我运行它时,代码会因以下错误而崩溃

 LINQ to Entities does not recognize the method 'System.String ToString()' method 

有谁知道如何解决这个错误? 而且,我是以正确的方式做到这一点,还是我应该采用与Phil Haack解释不同的方式,因为他使用Linq到SQL?

任何反馈都将非常感激。

谢谢伙计们。

EF不支持ToString方法,您必须在没有ToString和格式的情况下检索数据

这应该工作

 public ActionResult LinqGridData(string sidx, string sord, int page, int rows) { AssetEntities context = new AssetEntities(); var query = from e in context.Equipments select e; var count = query.Count(); var result = new { total = 1, page = page, records = count, rows = query.Select(x => new { x.equipamentID, x.Category.categoryTitle,x.Department.title }) .ToList() // .AsEnumerable() whatever .Select(x => new { id = x.equipamentID, cell = new string[] { x.equipamentID.ToString(), x.categoryTitle, x.title }}) .ToArray(), }; return Json(result, JsonRequestBehavior.AllowGet); } 

从另一个答案看代码示例。 我希望它会有所帮助。

小言评:

  1. sortname: 'Id'是错误的参数,因为您没有名为’Id’的列。 可能你的意思是sortname:'equipmentID'
  2. 你应该删除被删除的imgpath: '/scripts/themes/coffee/images'参数。
  3. 您应该从HTML代码中删除除id之外的所有属性:

啊,我找到了这个问题。 .ToString在LINQ to Entity中不起作用。 是的,这很奇怪,IMO非常愚蠢。 但这是核心问题。 至于解决方法…当JSON序列化事物时,无论如何,当jQuery到处读取它们时,它们最终看起来非常像字符串。 所以,基本上,你应该能够完全省略.ToString(),它应该工作。

我将解决内联编辑和向jqGrid添加新行的问题,因为它适用于ASP.NET MVC 3和Razor C#。 我还将包含C#Controller代码来填充网格并将数据保存到网格中。 首先让我们看看如何使用NuGet包管理器在MVC3 Web应用程序中安装jqGrid 4.4.1。

  1. 安装jQuery 1.7.2或更高版本。
  2. 安装jQuery.UI.Combined。
  3. 安装jqGrid 4.4.1

你可以单独下载jqGrid

http://www.trirand.com/blog/?page_id=6

并且可以在以下位置找到jqGrid文档

http://www.trirand.com/jqgridwiki/doku.php

我不打算在这篇文章中测试代码,但它基于可行的代码。 我将采用蛮力方法来解决从操作方法填充jqGrid,编辑单行或添加新的可编辑行,然后将行保存到操作方法这一困难而复杂的问题。 我相信可以找到更好的方法,但这是一个很好的起点。 我不打算告诉你如何调整你的jqGrid的外观,我会留给你。 我将使用JSON作为jqGrid和ASP.NET MVC 3之间的数据交换格式。我不打算在网格中删除行的问题。

让我们从Controller中的GET操作方法开始

 public JsonResult GetProduct(int productId = 0) { var productsQuery = dbContext.FirstOrDefault(p => p.ProductId == productId); var productsList = new List(); // SQL does not understand ToString() so we have to do this or something like it foreach(var p in productsQuery) { var product = new Product{ ProductId = p.ProductId, Product.Name = p.Name, Product.Date = p.Date.ToShortDateString() // and so on... }; productsList.Add(product); } // You must build an anonymous object that can then be converted into a 2-dimensional // array formatted for jqGrid, convert it to a 2d array then Json. Note that all grid // data must be in string format. var jsonData = new { total = 1, page = 1, records = productsQuery.Count(), rows = productsList.Select(p => new { id = p.id.ToString(), cell = new string[] { p.Name, p.Date.ToShortDateString(), // and so on... } }).ToArray(); }; return Json(jsonData, JsonRequestBehavior.AllowGet); } 

而观点……

  @using (Html.BeginForm("","", FormMethod.Post, new { id = "ProductsForm" })) { 
}

然后是POST方法

 [HttpPost] public JsonResult SaveProduct(FormCollection frm) { Product product; if (frm["oper"] == "add") { product = new Product(); } else { int productId = Int32.Parse(frm["id"]); product = dbContext.Products.FirstOrDefault(p => p.ProductId == productId); } foreach (var key in frmAllKeys) { switch(key) { case "Name": product.Name = frm[key]; break; case "Date": product.Date = DateTime.Parse(frm[key]); break; // and so on... } } try { if (frm["oper"] == "add") { dbContext.AddObject(product); } dbContext.SaveChanges(); } catch (Exception ex) { Debug.WriteLine(exception.StackTrace); return Json(false); } return Json(true); } 

有更好的方法来做到这一点,但这是一个良好的开端。 我没有解决动态网格问题。 我不确定如何才能实现。 我只想说动态jqGrid需要更多的JavaScript和/或C#代码。 我将看一下jqGrid中的“网格内的网格”function,用于将静态网格与动态网格相结合。

我确实尝试构建能够接受对象类型,记录列表并为网格生成jqGrid数组和Json数据的function,而无需执行上面显示的所有额外工作。 我认为可以通过反思完成,但我现在没时间做。

最后,我还尝试构建从FormCollection中提取数据的function,并仅在给定对象类型和FormCollection的情况下填充对象。 同样,我认为这可以使用reflection来完成,但我现在没有时间去做。 如果有人想尝试构建MVC3 C#jqGrid Json生成器和提取器,我会建议您使用entity framework代码优先方法和POCO类为您的模型。 对于这样的任务,POCO类比实体对象更容易使用。

我希望这有帮助 :)