asp.net mvc 3 webgrid的排序仍然保持不变?sortdir=ASC

17 浏览
0 Comments

asp.net mvc 3 webgrid的排序仍然保持不变?sortdir=ASC

我正在尝试使用asp.net mvc中的几个网格进行实验。

微软在mvc 3的预发布版本中也有一个网格,所以我决定试试那个。

基本功能很容易实现,但在排序方面遇到了一些问题。

该网格通过url来处理排序。在url中,以以下方式指定排序列和排序方向:

?sortdir=ASC&sort=ABONNEMENT

现在你会期望,在对某一列进行排序之后,该列的sortdir查询字符串会改变为?sortdir=DESC

但事实并非如此。它仍然是?sortdir=ASC。

有人知道这是一个bug还是一个特性,以及如何解决吗?

另一个非常恼人的事情是:如果我点击排序链接,会发送一个httpget请求。

因为这样我会丢失我的模型。因为页面上有可能对网格进行过滤(搜索功能),所以我希望在模型中保留这个功能。

在我看来,将这些数据放入模型状态比存储在会话状态中要简单和更清晰。

是否可能更改排序标题链接的行为,以执行httppost请求?

对此有任何想法或思考吗?

谢谢帮助。

问候,Koen

视图的代码如下:


订阅列表

<% using (Html.BeginForm("List", "Subscription", FormMethod.Post)) { %>
搜索依据 <%: Html.DropDownListFor(m => m.SearchByColumn, Ogone.FrontEnd.Web.Controllers.SubscriptionController.SubscriptionSearchList) %> <%: Html.TextBoxFor(m => m.SearchByText) %>
<% var grid = new System.Web.Helpers.WebGrid(Model.SubscriptionList, columnNames: new List(){"Title"}, canPage:false); %> <%= grid.GetHtml(columns: grid.Columns( grid.Column(format: (item) => Html.ActionLink("编辑", "Edit", new { id = item.ID })), grid.Column("ID"), grid.Column("ISP"), grid.Column("ABONNEMENT"), grid.Column("MODE"), grid.Column("SETUPFEE"), grid.Column("MONTHLYFEE")) ) %>

0
0 Comments

问题:asp.net mvc 3 webgrid sorting remains ?sortdir=ASC的出现原因及解决方法

在上述内容中,作者提到了一个问题:asp.net mvc 3 webgrid sorting remains ?sortdir=ASC。这个问题的出现原因是在通过WebGrid进行排序时,排序的参数(?sortdir=ASC)未能正确保留。

为了解决这个问题,作者提供了一个解决方法。作者通过向查询字符串集合中注入一个额外的参数来解决问题。这样,就可以将搜索过滤器放入查询字符串中。通常情况下,查询字符串集合是只读的,但作者找到了一些代码来修复这个问题。

以下是作者提供的代码示例,用于向查询字符串中添加参数:

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)
{
    // 检查查询字符串中的搜索过滤器
    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
    {
        // 将搜索过滤器添加到查询字符串中
        Common.QueryString.Add("search", SearchFilter);
        model.SubscriptionList = _subscriptionHandler.ReadWhereContains(SearchFilter);
    }
    if (Request.IsAjaxRequest())
    {
        return View("SubscriptionList", model);
    }
    else
    {
        return View("Index", model);
    }
}

如果有人对修复这个问题有更简洁的解决方案,欢迎提出建议。

0
0 Comments

问题的原因是网格列名必须与字段或属性相对应。生成网格标题中的URL的方法会将URL查询字符串中的“sort”与绑定的列和网格列名进行比较。这三者必须相同。如果列名的定义配置不正确,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"), <-- 这将抛出异常
grid.Column("LivesIn.City"),
grid.Column("LivesIn.Country")

但是,您可以使用格式设置,不会抛出异常:

grid.Column("FirstName"),
grid.Column("MyLastName", format: item => item.LastName),
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”具有正确的排序URL。

好了...如果我们不想暴露我们的域结构怎么办?那么我们需要在绑定过程中添加列名列表:

var grid = new WebGrid(persons, columnNames: new [] { "Foo" });
-- 或者 --
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" });
-- 或者 --
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" });
-- 或者 --
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(){"Title"},  
          canPage:false);

...或者在其中添加所有列名,如“ID”,“ISP”等。

非常丰富的信息。这可能应该被标记为“正确”。grid.Bind的讨论对我来说是相关的,并解决了我的问题。

这是一个非常好的答案,但是您的示例类都使用字段。您需要将它们切换为属性才能使示例正常工作,例如:public string FirstName { get; set;} 如果您尝试绑定到字段,将会得到“列'FirstName'不存在”的错误。

我认为您可以接受它作为答案。解释得很清楚。

0
0 Comments

问题原因:DESC没有切换到ASC的原因不明确,但是根据提供的代码和描述,可能是由于缺少ajaxUpdateContainerId属性导致的。

解决方法:添加ajaxUpdateContainerId属性并将其设置为一个div的ID。

整理后的文章如下:

我不确定为什么DESC没有切换到ASC。我有一个类似的例子,它工作得很好。尝试使用ajax容器(ajaxUpdateContainerId)。这可能有所帮助,如果没有其他问题,它还可以解决你在httpget请求中遇到的问题,保持搜索结果。下面是我的代码(我使用的是razor,但是应该很容易转换)。

只需要添加一个新属性:ajaxUpdateContainerId: "div_name"

用一个ID为div_name的div来包装网格。

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

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

0