ASP.Net MVC 3 JQGrid - PullRequest
       60

ASP.Net MVC 3 JQGrid

7 голосов
/ 23 февраля 2011

После прочтения элемента управления JQGrid я решил, что было бы неплохо использовать его в одном из моих веб-приложений ASP.Net MVC 3.

Сначала я следовал учебному пособию Фила Хаака http://haacked.com/archive/2009/04/14/using-jquery-grid-with-asp.net-mvc.aspxчто все хорошо.Затем я попытался внедрить нечто подобное в свое приложение, с той лишь разницей, что я использую Linq To Entities.

На странице моего просмотра импортированы все классы 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 to SQL?

Любая обратная связь будет принята с благодарностью.

Спасибо, народ.

Ответы [ 4 ]

14 голосов
/ 23 февраля 2011

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

}
3 голосов
/ 23 февраля 2011

Посмотрите на пример кода из другого ответа .Надеюсь, это будет полезно.

Небольшие замечания:

  1. sortname: 'Id' - неверный параметр, поскольку у вас нет столбца с именем 'Id'.Возможно, вы имеете в виду sortname:'equipmentID'.
  2. Вы должны удалить imgpath: '/scripts/themes/coffee/images' параметр jqGrid, который ограничен .
  3. Вы должны удалить все атрибуты, кроме id из кода HTML:<table id="list"></table><div id="pager"></div>
0 голосов
/ 01 ноября 2012

Я рассмотрю вопрос о встроенном редактировании и добавлении новой строки в jqGrid применительно к ASP.NET MVC 3 и Razor C #.Я также включу код контроллера C # для заполнения сетки и сохранения данных в сетке.Сначала давайте рассмотрим, как установить jqGrid 4.4.1 в веб-приложении MVC3 с помощью диспетчера пакетов NuGet.

  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. Я не собираюсь решать проблему удаления строки в сетке.

Давайте начнем с метода действия GET вКонтроллер

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.Опять же, я думаю, что это можно сделать с помощью рефлексии, но у меня нет времени, чтобы сделать это прямо сейчас.Если кто-то захочет создать генератор и экстрактор Json MVC3 C # jqGrid, я рекомендую вам использовать метод Entity Framework Code First с классами POCO для вашей модели.С классами POCO гораздо проще работать, чем с объектами-сущностями для такой задачи.

Надеюсь, это поможет:)

0 голосов
/ 23 февраля 2011

Ах, я нашел проблему..ToString не работает в LINQ to Entity.Да, это странно, и IMO очень тупой.Но это основная проблема.Что касается обходного пути ... когда JSON сериализует вещи, они в конечном итоге выглядят очень похоже на строку, когда jQuery начинает читать их.Поэтому, по сути, вы должны быть в состоянии полностью опустить .ToString (), и он должен работать.

...