Guidance on a better way to retain filtering options when using ASP.NET MVC 2

随声附和 提交于 2019-11-29 15:54:38

It seems to me that the best way in to divide some actions which provide pure data for the jqGrid from other controller action. Such jqGrid-oriented actions can have prototype like:

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

I personally prefer to implement this part as WCF service and to have this WCF service as a part of the same ASP.NET site. In general it's much more the matter of taste and depends on your other project requirements.

This part of you ASP.NET site could implement users authentication which you need and can be tested with unit tests exactly like other actions of your controllers.

The views of the ASP.NET MVC site can have empty data for jqGrids, and have only correct URLs and probably generate the HTML code depends on the users permission in the site. Every page will fill the data of jqGrids with respect of the corresponds requests to the server (request to the corresponding GetData action).

You can use HTTP GET for the data for the best data caching. The caching of data is the subject of a separate discussion. If you do this, you should use prmNames: { nd:null } in the definition of jqGrid to remove unique nd parameter with the timestamp added per default to every GET request. To have full control of the data caching on the server side you can for example add in HTTP headers of the server responses both "Cache-Control" set to "max-age=0" and "ETag" header with the value calculated based of the data returned in the response. You should test whether the request from the client has "If-None-Match" HTTP header with the value of "ETag" coresponds the data cached on the client. Then you should verify whether the current data on the server (in the database) are changed and, if there are not changed, generate a response with an empty body (set SuppressEntityBody to true) and return "304 Not Modified" status code (HttpStatusCode.NotModified) instead of default "200 OK". A more detail explanation is much more longer.

If you don't want optimize you site for caching of HTTP GET data for jqGrids you can either use HTTP POST or don't use prmNames: { nd:null } parameter.

The code inside of JsonResult GetData(string filter, string sidx, string sord, int page, int rows) is not very short of cause. You should deserialise JSON data from the filter string and then construct the request to the data model depends on the method of the data access which you use (LINQ to SQL, Entity Model or SqlCommand with SqlDataReader). Because you have this part already implemented it has no sense to discuss this part.

Probably the main part of my suggestion is the usage of clear separation of controller actions which provide the data for all your jqGrids and the usage of MVC views with empty data (having only <table id="list"></table><div id="pager"></div>). You should also has no doubt with having a relative long code for analyzing of filters which come from the Advance Searching feature of the jqGrid and generating or the corresponding requests to your data model. Just implement it one time. In my implementation the code in also relatively complex, but it is already written one time, it works and it can be used for all new jqGrids.

I made this once, very simple.

pseudo code:

Controller

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

Now Create A RenderPartial:

PartialView

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

And create a view that implements your Jquery, other components+your partialView

View

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

I hope this helps, this is according to the MVC- mv-mv-c principle ;) Model-View -(modelview) - control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!