【问题标题】:asp.net mvc 3 webgrid sorting remains ?sortdir=ASCasp.net mvc 3 webgrid 排序仍然存在 ?sortdir=ASC
【发布时间】:2011-05-29 22:00:07
【问题描述】:

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

基本功能很容易实现,但在排序方面,我遇到了一些问题。 网格按 url 处理其排序。在 url 中,您具有以下方式的排序列和排序方向: ?sortdir=ASC&sort=ABONNEMENT

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

另外一件很烦人的事:如果我点击一个排序链接,一个 httpget 请求就完成了。 正因为如此,我失去了我的模型。因为页面上有可能过滤网格(搜索功能),所以我想将其保留在模型中。 在我看来,将这些数据置于模型状态,而不是将其存储在会话状态中,这将是一个更容易和更清洁的解决方案。 是否可以更改排序标题链接的行为以便执行 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>

【问题讨论】:

  • 非常想知道是否有办法强制 webgrid 发布而不是 get 进行排序和分页。
  • 如果你的表不是太大,也许你可以在客户端使用 jquery.tablesorter 进行排序?

标签: asp.net-mvc webgrid


【解决方案1】:

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

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

这里我们有示例域类来显示

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

public class Address
{
    public string Country;
    public string City;
}

现在让我们显示列表

将列名用作字段

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

...所有列都有正确的排序url

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

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

但是可以使用format,不会抛出异常

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

...但是 MyLastName 列的排序 url 会很糟糕!一直sortDir=ASC

您需要使用好的列名来拥有正确的排序 url 和自定义格式,所以...

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

....哇...一切都好..那是错误的孩子..列“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 列有正确的排序 url

但是要小心!!!还有一个错误。

如果我们将手动列名称添加到绑定中,那么所有列将被跳过,直到找到手动列。示例:

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”的排序 url ... 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")

@科恩

在此处删除代码中的 columnNames

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

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

【讨论】:

  • 信息丰富。这可能应该被标记为“正确”。 grid.Bind 的讨论与我相关并解决了我的问题。
  • 这是一个很好的答案,但是您的示例类都在使用字段。您需要将它们切换到属性才能使您的示例正常工作,例如公共字符串名字 { 获取; set;} 如果你尝试绑定到字段,你会得到一个 Column "FirstName" does not exist 错误。
  • 我认为您可以接受它作为答案。很好解释
【解决方案2】:

我一直在考虑解决该问题的方法,并且找到了。

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

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

将参数添加到查询字符串的代码:

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

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

【讨论】:

    【解决方案3】:

    我不确定为什么 DESC 不切换到 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>
    

    祝你好运,希望对你有帮助!

    【讨论】:

      【解决方案4】:

      我通过设置 'SortColumn' 属性在 MVC 4 中解决了这个问题。网格的“排序”查询字符串参数的值。:

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

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

      【讨论】:

      • @Leanid Minkov,你的简单修复让它对我也有用。谢谢。
      猜你喜欢
      • 1970-01-01
      • 2011-11-18
      • 2011-08-13
      • 2011-06-30
      • 1970-01-01
      • 2011-05-10
      • 2012-04-18
      • 1970-01-01
      • 2013-08-26
      相关资源
      最近更新 更多