Руководство по улучшению способа сохранения параметров фильтрации при использовании ASP.NET MVC 2 - PullRequest
2 голосов
/ 23 июля 2010

У меня есть приложение ASP.NET MVC 2, которое частично позволяет пользователю фильтровать данные и просматривать эти данные в JQGrid.

В настоящее время это состоит из контроллера, который инициализирует мою модель фильтра и настраивает, как я хочу, чтобы моя сетка отображалась. Эта информация используется представлением и частичным представлением для отображения фильтра и оболочки сетки. Я использую шаблон редактора для отображения моего фильтра. JQGrid использует действие контроллера JsonResult (GET) для извлечения результатов фильтра (с добавлением подкачки, предлагаемой сеткой - по запросу GET возвращается только одна страница данных. Uri, используемый сеткой запрашиваемые данные содержат модель фильтра в виде RouteValue - и в настоящее время содержат строковое представление текущего состояния фильтра. Пользовательский IModelBinder используется для преобразования этого представления обратно в экземпляр класса модели фильтра.

Пользователь может изменить фильтр и нажать кнопку отправки, чтобы получить другие результаты - это затем вызывается действием (HttpPost) ViewResult, которое принимает модель фильтра - воссоздается дополнительным связующим звеном модели и приводит к тому, что оболочка сетки становится обновлен.

Итак, у меня есть:

FilterModel Представляет желаемые пользовательские характеристики фильтрации

FilterModelEditorTemplateSubmissionBinder: DefaultModelBinder - используется для преобразования информации запроса, предоставленной пользователем, при изменении его характеристик фильтрации в соответствующий экземпляр FilterModel.

FilterModelStringRepresentationBinder: IModelBinder - используется для преобразования закодированного фильтра из запроса GET JQGrid для данных, чтобы был сделан правильный запрос службы, которая в конечном итоге выполняет запрос и возвращает соответствующие данные.

ViewResult Index () - создает фильтр по умолчанию, настраивает спецификацию сетки и возвращает представление для отображения шаблона редактора фильтра и оболочки сетки.

[HttpPost] Фильтр ViewResult (фильтр FilterModel) - принимает новые характеристики фильтра и возвращает то же представление, что и Index (). Использует FilterModelEditorTemplateSubmissionBinder для привязки модели фильтра.

JsonResult GetData (фильтр FilterModel, строка sidx, sord строки, строка int, строки int) - вызывается из JQGrid для извлечения данных. Использует FilterModelStringRepresentationBinder для привязки модели фильтра.

Как сложность, моя модель фильтра содержит опцию для выбора одного значения из коллекции элементов. Эта коллекция извлекается из запроса на обслуживание, и я не хочу продолжать запрашивать эти данные каждый раз, когда показываю фильтр, в настоящее время я получаю его, если свойство имеет нулевое значение, а затем включаю параметры, скрытые в шаблоне редактора и кодировку в строковое представление. Эти параметры затем восстанавливаются соответствующим связующим для модели.

Хотя этот подход работает, я не могу не чувствовать, что мне нужно заново изобретать viewstate, чтобы сохранить мой фильтр и включенные опции. Поскольку я новичок в ASP.NET MVC, но очень доволен классическими ASP и ASP.NET Web Forms, я подумал, что я добавлю это для комментариев и рекомендаций, чтобы найти способ, который более точно соответствует шаблону MVC.

Ответы [ 2 ]

0 голосов
/ 30 июля 2010

Мне кажется, что лучше всего отделить некоторые действия, которые предоставляют чистые данные для jqGrid, от других действий контроллера.Такие jqGrid-ориентированные действия могут иметь такой прототип, как:

JsonResult GetData(string filter, string sidx, string sord, int page, int rows)

Я лично предпочитаю реализовать эту часть как службу WCF и использовать эту службу WCF как часть того же сайта ASP.NET.В общем, это намного больше вопрос вкуса и зависит от других требований вашего проекта.

Эта часть вашего сайта ASP.NET может реализовывать аутентификацию пользователей, которая вам нужна, и может быть протестирована с помощью модульных тестов точно так же, как другие действияваши контроллеры.

Представления сайта ASP.NET MVC могут содержать пустых данных для jqGrids, иметь только правильные URL-адреса и, возможно, генерировать HTML-код, в зависимости от разрешения пользователей на сайте.,Каждая страница будет заполнять данные jqGrids соответствующими запросами к серверу (запрос к соответствующему действию GetData).

Вы можете использовать HTTP GET для данных длялучшее кэширование данных.Кеширование данных является предметом отдельного обсуждения.Если вы сделаете это, вы должны использовать prmNames: { nd:null } в определении jqGrid, чтобы удалить уникальный параметр nd с отметкой времени, добавляемой по умолчанию к каждому запросу GET.Чтобы получить полный контроль над кэшированием данных на стороне сервера, вы можете, например, добавить в заголовки HTTP ответов сервера оба параметра: "Cache-Control", установленный в "max-age=0", и заголовок "ETag" со значением, рассчитанным на основе данных, возвращаемых в ответе.,Вы должны проверить, имеет ли запрос от клиента "If-None-Match" заголовок HTTP со значением "ETag" coresponds данные, кэшированные на клиенте.Затем вы должны проверить, изменены ли текущие данные на сервере (в базе данных), и, если они не были изменены, сгенерировать ответ с телом empty (для SuppressEntityBody установлено значение true) и вернуть «304 Не изменено»код состояния (HttpStatusCode.NotModified) вместо значения по умолчанию «200 OK».Более подробное объяснение гораздо длиннее.

Если вы не хотите оптимизировать свой сайт для кэширования данных HTTP GET для jqGrids, вы можете либо использовать HTTP POST, либо не использовать параметр prmNames: { nd:null }.

Код внутри JsonResult GetData(string filter, string sidx, string sord, int page, int rows) не слишком важен.Вы должны десериализовать данные JSON из строки filter и затем построить запрос к модели данных в зависимости от метода доступа к данным, который вы используете (LINQ to SQL, Entity Model или SqlCommand с SqlDataReader).Поскольку эта часть уже реализована, обсуждать ее нет смысла.

Вероятно, основная часть моего предложения - это использование четкого разделения действий контроллера, которые предоставляют данные для всех ваших jqGrids, и использованиеMVC просматривает с пустыми данными (имеющими только <table id="list"></table><div id="pager"></div>).Вы также не должны сомневаться в наличии относительного длинного кода для анализа фильтров, которые исходят из функции расширенного поиска jqGrid, и для генерации или соответствующих запросов к вашей модели данных.Просто осуществите это один раз.В моей реализации код также относительно сложен, но он уже написан один раз, он работает, и его можно использовать для всех новых jqGrids.

0 голосов
/ 29 июля 2010

Я сделал это один раз, очень просто.

псевдокод:

Контроллер

[HttpGet]
public ActionResult getList(int? id){
    return PartialView("Index", new ListViewModel(id??0))
}

ViewModel

public class ListViewModel{
//ObjectAmountPerPage is the amount of object you want per page, you can modify this as //parameter so the user
//can choose the amount

public int ObjectAmountPerPage = 20 //you can make this into a variable of any sort, db/configfile/parameter

public List<YourObjectName> ObjectList;
public int CurrentPage;
    public ListViewModel(id){
        Currentpage = id;
        using (MyDataContext db = new MyDataContext()){
            ObjectList = db.YourObjectName.OrderBy(object=>object.somefield).getListFromStartIndexToEndIndex(id*ObjectAmountPerPage ,(id*ObjectAmountPerPage) +20).toList();
        }
    }
}

Теперь создайте RenderPartial:

PartialView

<@page inherit="IEnumerable<ListViewMode>">
<%foreach(YourObjectName object in Model.ObjectList){%>
 Create a table with your fields
<%}%>

И создать представление, которое реализует ваш Jquery, другие компоненты + ваш частичный просмотр

Представление

<javascript>
    $(function(){
        $("#nextpage").click(function(){
          (/controller/getlist/$("#nextpage").val(),function(data){$("#yourlist").html = data});
        });
    });
</javascript>
<div id="yourlist">
    <%=Html.RenderPartial("YourPartialView", new ListViewModel())%>
</div>
<something id="nextpage" value"<%=Model.CurentPage+1%>">next page</something>

Я надеюсь, что этопомогает, это по принципу MVC-mv-mv-c;) Model-View - (viewview) - control

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...