ASP.Net MVC 3 JQGrid
после чтения на элементе управления JQGrid, я решил, что было бы хорошо использовать его в одном из моих ASP.Net MVC 3 веб-приложения.
во-первых, я следовал Фил Haacks учебник http://haacked.com/archive/2009/04/14/using-jquery-grid-with-asp.net-mvc.aspx что все хорошо. Затем я попытался реализовать что-то подобное в своем приложении, с той лишь разницей, что я использую Linq для сущностей.
на моей странице просмотра импортированы все классы css и Jquery, затем у меня есть моя функция JavaScript и таблица, которая содержит данные
<script type="text/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'
});
});
<h2>My Grid Data</h2>
<table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>
<div id="pager" class="scroll" style="text-align:center;"></div>
тогда в моем контроллере у меня есть следующий метод, который должен возвращать данные 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
кто-нибудь знает как исправить эту ошибку? А также, я делаю это правильно, или я должен делать это по-другому от объяснения Фила Хаака, так как он использует Linq для В SQL?
любая обратная связь была бы очень признательна.
Спасибо Ребята.
4 ответов
EF не поддерживает метод ToString, вы должны получить данные без ToString и format
это должно работать
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);
}
посмотрите на пример кода другого ответа. Надеюсь, это поможет.
небольшие замечания:
-
sortname: 'Id'
неверный параметр, потому что у вас нет столбца с именем "Id". Вероятно, вы имеете в видуsortname:'equipmentID'
. - вы должны удалить
imgpath: '/scripts/themes/coffee/images'
параметр jqGrid, который является depricated. - вы должны удалить все атрибуты, кроме id из HTML-кода:
<table id="list"></table><div id="pager"></div>
Ах, я нашел проблему. .ToString не работает в LINQ to Entity. Да, это странно и очень глупо. Но это основная проблема. Что касается обходного пути...когда JSON сериализует вещи, они в конечном итоге выглядят очень похоже на строку в любом случае, к тому времени, когда jQuery добирается до их чтения. Так что, по сути, вы должны быть в состоянии полностью исключить .ToString() и он должен работать.
Я рассмотрю проблему встроенного редактирования и добавления новой строки в jqGrid, как это применимо к ASP.NET MVC 3 и бритва C#. Я также включу код контроллера C# для заполнения сетки и сохранения данных в сетку. Сначала давайте посмотрим, как установить jqGrid 4.4.1 в веб-приложении MVC3 с помощью диспетчера пакетов NuGet.
- установите jQuery 1.7.2 или выше.
- установить jQuery.ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС.Комбинированный.
- установить 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. Я не собираюсь решать проблему удаления строки в сетке.
давайте начнем с метода GET action в Контроллер
public JsonResult GetProduct(int productId = 0)
{
var productsQuery = dbContext.FirstOrDefault(p => p.ProductId == productId);
var productsList = new List<Products>();
// 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);
}
и посмотреть...
<script type="text/javascript">
$(document).ready(function () {
var lastSelectedId;
var grid = $('#grid');
grid.jqGrid({
url: "@Url.Action("GetProducts", "Products")",
datatype: 'json',
mtype: 'post',
colNames: ['ProductId', 'Name', 'Date',
// and so on...
],
colModel: [
{ name: 'ProductId', index: 'ProductId', editable: false },
{ name: 'Name', index: 'Name', editable: true, edittype: 'text' },
{ name: 'Date', index: 'Date', editable: true, edittype: 'text' }
// and so on...
],
onSelectRow: function(rowid) {
if (rowid && rowid !== lastSelectedId) {
grid.jqGrid('resotreRow', lastSelectedId);
lastSelectedId = rowid;
}
grid.jqGrid('editRow', rowid, { keys: true });
},
editurl: "@Url.Action("SaveProducts", "Products");
rownum: [10],
rowList: [5,10,20,50],
pager: '#grid_pager',
sortName: 'Name',
viewrecords: true,
gridview: true,
caption: 'Sample Grid'
});
grid.jqGrid('navGrid', '#pager', { edit: false, add: false: del: false,
refresh: false });
grid.jqGrid('inlineNav', '#pager', {
addParams: {
position: 'first',
addRowParams: {
keys: true,
oneditfunc: onInlineEdit
}
add: true,
edit: false,
save: false,
cancel: true
});
function onInlineEdit(rowid) {
// add inline editing functionality here
}
</script>
@using (Html.BeginForm("","", FormMethod.Post, new { id = "ProductsForm" }))
{
<table id="grid">
</table>
<div id="pager">
</div>
}
а затем метод 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 для объединения статической сетки с динамической сетка.
Я попытался создать функциональность, которая приняла бы тип объекта, список записей и генерировать массив jqGrid и данные Json для сетки без необходимости выполнять всю дополнительную работу, показанную выше. Я думаю, что это можно сделать с помощью размышлений, но у меня нет времени делать это прямо сейчас.
наконец, я также попытался создать функциональность, которая будет извлекать данные из FormCollection и заполнять объект, заданный только тип объекта и FormCollection. Опять же, я думаю, что это можно сделать с помощью отражения, но у меня нет времени делать это прямо сейчас. Если кто-то хочет попытаться построить генератор и экстрактор MVC3 C# jqGrid Json, я бы рекомендовал использовать первый метод кода Entity Framework с классами POCO для вашей модели. Классы POCO намного проще работать с объектами entity для такой задачи.
надеюсь, это поможет:)