首页 文章

asp.net mvc 3 webgrid排序仍然存在?sortdir = ASC

提问于
浏览
12

我在asp.net mvc中尝试了几个网格 . 微软在mvc 3的预发布中也知道了一个网格,所以我想我会试试那个 .

基本功能很容易实现,但是当涉及到排序时,我遇到了一些问题 . 网格通过URL处理其排序 . 在url中,您可以通过以下方式获得排序列和排序方向:?sortdir = ASC&sort = ABONNEMENT

现在您可以期望在对某列进行排序后,该列上的sortdir查询字符串将更改为?sortdir = DESC但它不会 . 它保持?sortdir = ASC . 有人知道这是一个错误还是一个功能,以及如何解决这个问题?

另一个非常恼人的事情:如果我点击一个排序链接,就会完成一个httpget请求 . 因此,我放松了我的模型 . 因为页面上有可能过滤网格(搜索功能),所以我想在模型中保留它 . 在我看来,将这些数据置于模型状态,而不是将其存储在会话状态中,这将是一个更容易和更清晰的解决方案 . 是否可以更改排序 Headers 链接的行为,以便执行http帖子?

对此有何想法或想法? Tnx的帮助 .

格雷茨,科恩

视图的代码如下:

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<table>
    <tr>
        <td>
            <h1 class="normal">List of subscription</h1>
        </td>
        <td>

        </td>
    </tr>
</table>
<% using (Html.BeginForm("List", "Subscription", FormMethod.Post)) { %>

<table border="0" cellpadding="0" cellspacing="5">
    <tr>
        <td>
            Search By
        </td>
        <td>
            <%: Html.DropDownListFor(m => m.SearchByColumn, Ogone.FrontEnd.Web.Controllers.SubscriptionController.SubscriptionSearchList) %>
        </td>
        <td>
            <%: Html.TextBoxFor(m => m.SearchByText) %>
        </td>
        <td>
            <input name="button" type="submit" value="Search" />
        </td>
    </tr>
</table>

<div>
<%  
var grid = new System.Web.Helpers.WebGrid(Model.SubscriptionList,  
              columnNames: new List<string>(){"Title"},  
              canPage:false);  
 %> 
<%= grid.GetHtml(columns: grid.Columns(
             grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.ID })),
             grid.Column("ID"),
             grid.Column("ISP"),
             grid.Column("ABONNEMENT"),
             grid.Column("MODE"),
             grid.Column("SETUPFEE"),
             grid.Column("MONTHLYFEE"))
             ) %>
</div>

4 回答

  • 2

    发生这种情况是因为网格列名称必须与您的字段或属性相对应 . 在网格 Headers 中生成网址的方法将来自网址查询字符串的“排序”与有界列和网格列名称进行比较 . 他们三个必须是一样的 . 如果未正确配置列名称的定义,则无法正确生成URL .

    无论如何..这里是一些正确定义的列名称的例子 .

    这里我们有要显示的示例域类

    public class Person
    {
        public string FirstName;
        public string LastName;
        public Address LivesIn;
    }
    
    public class Address
    {
        public string Country;
        public string City;
    }
    

    现在让我们显示List

    将列名称用作字段

    grid.Column("FirstName"),
    grid.Column("LastName"),
    grid.Column("LivesIn.City"),
    grid.Column("LivesIn.Country")
    

    ...所有列都有正确的排序网址

    如果您在列名中输入拼写错误,则会出现异常

    grid.Column("FirstName"),
    grid.Column("MyLastName"), <-- this throws exception
    grid.Column("LivesIn.City"),
    grid.Column("LivesIn.Country")
    

    但是你可以使用格式,并且不会抛出任何异常

    grid.Column("FirstName"),
    grid.Column("MyLastName", format: item => item.LastName</text>),
    grid.Column("LivesIn.City"),
    grid.Column("LivesIn.Country")
    

    ...但是为MyLastName列排序网址会很糟糕!始终sortDir = ASC

    你需要使用好的列名来有适当的排序网址和自定义格式,所以......

    grid.Column("FirstName"),
    grid.Column("LastName", format: item => item.LastName),
    grid.Column("LivesIn.City"),
    grid.Column("LivesIn.Country")
    

    ... 一切都好

    复杂类型怎么样?

    grid.Column("FirstName"),
    grid.Column("LastName"),
    grid.Column("LivesIn.MyNonExistingField", format: item => item.LivesIn.City),
    grid.Column("LivesIn.Country")
    

    ....哇......一切都很好..这是bug的小孩..专栏“LivesIn.MyNonExistingField”有适当的排序网址 .

    好的...如果我们不想公开我们的域结构怎么办?然后我们需要在绑定期间添加列名列表

    var grid = new WebGrid(persons, columnNames: new [] { "Foo" });
    -- or --
    grid.Bind(persons, columnNames: new [] { "Foo" });
    
    grid.Column("Foo", format: item => item.FirstName),
    grid.Column("LastName"),
    grid.Column("LivesIn.MyNonExistingField", format: item => item.LivesIn.City),
    grid.Column("LivesIn.Country")
    

    ..现在Foo列有适当的排序网址

    但小心!!!还有另一个错误 .

    如果我们将手动列名称添加到绑定,则将跳过所有列,直到找到手动列 . 示例:

    var grid = new WebGrid(persons, columnNames: new [] { "Foo" });
    -- or --
    grid.Bind(persons, columnNames: new [] { "Foo" });
    
    grid.Column("FirstName"),
    grid.Column("Foo", format: item => item.LastName),
    grid.Column("LivesIn.MyNonExistingField", format: item => item.LivesIn.City),
    grid.Column("LivesIn.Country")
    

    ...排序网址“FirstName”的网址将无法正确生成... sortDir = ASC一直...修复此项还添加“FirstName”作为列名,如下所示:

    var grid = new WebGrid(persons, columnNames: new [] { "FirstName", "Foo" });
    -- or --
    grid.Bind(persons, columnNames: new [] { "FirstName", "Foo" });
    
    grid.Column("FirstName"),
    grid.Column("Foo", format: item => item.LastName),
    grid.Column("LivesIn.MyNonExistingField", format: item => item.LivesIn.City),
    grid.Column("LivesIn.Country")
    

    @Kohen

    在此处删除代码中的columnNames

    var grid = new System.Web.Helpers.WebGrid(Model.SubscriptionList,  
              columnNames: new List<string>(){"Title"},  
              canPage:false);
    

    ...或者添加所有列名称,如“ID”,“ISP”等

  • 24

    我一直在考虑解决问题的方法,我找到了一个 .

    我在querystring集合中注入了一个额外的参数 . 这样我就可以将搜索过滤器放入查询字符串中 .

    通常,查询字符串集合是只读的,但我找到了一些代码来解决这个问题 .

    用于向querystring添加参数的代码:

    public static void Add(string name, string value)
                {
                        NameValueCollection qs = System.Web.HttpContext.Current.Request.QueryString;
                        qs = (NameValueCollection)System.Web.HttpContext.Current.Request.GetType().GetField("_queryString", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(System.Web.HttpContext.Current.Request);
                        PropertyInfo readOnlyInfo = qs.GetType().GetProperty("IsReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
                        readOnlyInfo.SetValue(qs, false, null);
                        qs[name] = value;
                        readOnlyInfo.SetValue(qs, true, null);
                }
    

    新控制器代码:

    public ActionResult Index(string SearchFilter)
                {
                        // check querystring search
                        if (string.IsNullOrEmpty(SearchFilter) && !String.IsNullOrEmpty(Request.QueryString["search"]))
                                SearchFilter = Request.QueryString["search"];
    
                        var model = new Models.SubscriptionListModel { SearchFilter = SearchFilter };
    
                        if (string.IsNullOrEmpty(SearchFilter))
                        {
                                model.SubscriptionList = _subscriptionHandler.ReadWhereIdLessThanThousand();
                        }
                        else
                        {
                                // add search filter to the querystring
                                Common.QueryString.Add("search", SearchFilter);
                                model.SubscriptionList = _subscriptionHandler.ReadWhereContains(SearchFilter);
                        }
    
                        if (Request.IsAjaxRequest())
                        {
                                return View("SubscriptionList", model);
                        }
                        else
                        {
                                return View("Index", model);
                        }
                }
    

    如果有人有更清洁的解决方案来解决这个问题,建议仍然欢迎:-)

  • 1

    我'm not sure why DESC isn' t切换到ASC . 我有一个类似的例子,它工作得很好 . 使用ajax容器( ajaxUpdateContainerId )进行测试 . 这可能有所帮助,如果没有别的,它将解决您使用httpget请求的问题,维护您的搜索结果 . 这就是我所拥有的:(我正在使用剃须刀,但应该很容易转换) .

    只需添加新属性:ajaxUpdateContainerId:“ div_name

    用ID为 div_name 的div包裹网格

    @{
    var grid = new System.Web.Helpers.WebGrid(Model.SubscriptionList, canPage:false, ajaxUpdateContainerId: "grid");  
    }
    <div id="grid">
        @grid.GetHtml(columns: grid.Columns(  
        grid.Column(format:(item) => Html.ActionLink("Edit", "Edit", new { id=item.Id })),
        grid.Column("ISP"),
        grid.Column("ABONNEMENT"))) 
    </div>
    

    祝你好运,希望它有所帮助!

  • 1

    我通过设置'SortColumn'道具修复了MVC 4中的这个问题 . 网格的值“sort”查询字符串参数:

    grid = new WebGrid(...
    grid.Bind(Model...
    
    grid.SortColumn = this.Request.QueryString["sort"];
    
    @grid.GetHtml(columns:...
    

    我注意到我的模型'SortColumn'道具中的'Date'列 . 无论“排序”查询字符串参数的值如何,都设置为默认排序列的名称...

相关问题