Webforms SelectMethod和modelbinder过滤转到第一页

时间:2013-11-06 10:06:15

标签: webforms asp.net-4.5

我正在使用GridView的SelectMethod,我使用ModelBnding。简化视图:

<asp:GridView AllowPaging="True" 
        AllowSorting="True"
        runat="server"
        PageSize="10" 
        SelectMethod="GetRedirections"
        ID="rediretionGrid" AutoGenerateColumns="False" 
        ItemType="TTC.TT.Entities.ViewModels.Redirections.RedirectionView"
        DataKeyNames="Id"
        >
...
</asp:GridView>

背后的代码:

public IQueryable<RedirectionView> GetRedirections2([Control] string filter)
{
    var mappings = RedirectionService.GetRedirections().Where(x => x.Source.Contains(filter)).AsQueryable();

    // Setting PageIndex to 0 doesn't solve the problem.
    rediretionGrid.PageIndex = 0;
    return mappings;
}

当过滤器被设置为流行的多个结果返回时(例如2000),用户可以转到不同的分页页面(例如,他将转到第30页),不幸的是,当他将过滤器更改为不受欢迎的内容时返回的结果很多(例如3个结果)DataGrid将显示“找不到项目”的信息,因为DataGrid会保留用户在远处页面上的信息(30)并且他正试图显示该页面新的过滤。如果用户在第一页上,一切正常。什么是解决方法?如何在更改过滤器时将用户发送到第一页(或将显示结果的任何其他页面,通常是最后一页),或者做一些事情以避免在DataGrid即使多个记录时也没有显示任何内容的情况被发现了。

我的PageIndex为0的实验并没有解决问题(他们引入了更多问题,但我只是想提一下,以防有人提出这个答案)。当我将PageIndex设置为0时,仍然没有显示任何结果DataGrid。

为了说清楚,我知道如何解决这个问题,但实施时间很长,我无法相信M $可能不会发生这种情况。因为如果我被迫实现额外的事件监听器并添加自定义逻辑来处理这种情况,使用带有SelectMethod的ModelBinding是没有意义的,那就不值得了,因为编写这个自定义逻辑需要更多时间,然后不使用SelectMethod和ModelBinding。

更新 使用SelectMethod的返回类型进行的简单实验表明,当我将GetRedirection2方法的定义更改为:

public IEnumerable<RedirectionView> GetRedirections2(int maximumRows, int startRowIndex, out int totalRowCount, string sortByExpression, [Control] string filter)

我自己进行分页和排序,并尝试将PageIndex设置为0,如:

if (startRowIndex > totalRowCount)
{
    rediretionGrid.PageIndex = 0;
}

现在设置它并不能解决问题,因为它已经为时已晚。我相信DataGrid仍然存储它的startRowIndex并在返回后使用它来处理数据。最后它使用PageIndex并假装显示第0页,当它真正显示不同的页面时。所以我想要的是一个改变startRowIndex的方法,比如将一个参数标记为out就像处理totalRowCount一样。

1 个答案:

答案 0 :(得分:0)

我能够实现的最简单,最快捷的方式,但就我希望看到的是一个完整的页面重新加载而言,这也是一种可怕的方式。所以,我回到了原来的GetRedirections2方法定义。出于可见性原因,以下代码已简化:

public IQueryable<RedirectionView> GetRedirections2([Control] string filter)
{
    var mappings = RedirectionService.GetRedirections().Where(x => x.Source.Contains(filter));

    // This is a terrible hack to redirect user to a first page.
    if (rediretionGrid.PageIndex * rediretionGrid.PageSize > mappings.Count)
    {
        Response.Redirect(Paths.Redirections.Index_aspx + "?filterValue=" + filter);
    }
    return mappings.AsQueryable();
}

在Page_Load:

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack) return;
    var filterValue = Request.QueryString["filterValue"];
    filter.Text = filterValue;
}

我希望有一种正确的方法,不需要像这样实施黑客攻击:(