我如何在Asp.net MVC和实体框架中进行分页时应用过滤器? [英] How to I apply filter while paginating in Asp.net MVC and entity Framework?

查看:75
本文介绍了我如何在Asp.net MVC和实体框架中进行分页时应用过滤器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用ASP.NET MVC框架编写的Web应用程序.在我的Homecontroller中,我有一个名为Index的动作,该动作响应Get的请求.在此操作中,我使用IPagedList库创建页面以将记录分成多个页面.我的Index@HttpGet看起来像这样

I have a web app that is written using ASP.NET MVC framework. In my Homecontroller I have an action called Index which responds to a Get request. In this action, I create pages using IPagedList library to break the records into multiple pages. My Index@HttpGet looks something like this

public ActionResult Index(int? id)
{
    using(var connection = new Context())
    {
        int pageNumber = (id ?? 1);
        var presenter = new Presenter
        {
            Presenter = pageNumber,
            Tasks = connection.Tasks.ToPagedList(pageNumber, 30),
            Form = new TasksFiltersViewModel()
        }

        return View(presenter);
    }
}

我还有一个名为Index的动作,该动作响应Post请求并应用了一些过滤器.因此,在Post请求中,我做了类似的事情

I also have an action called Index that respond to the Post request which apply some filters. So in the Post request I do something like this

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(Presenter model)
{
    int pageNumber = (id ?? 1);
    if (ModelState.IsValid)
    {
        using(var connection = new Context())
        {
            model.Tasks = connection.Tasks
                                    .Where(task => task.Status == 5)
                                    .ToPagedList(pageNumber, 30);
        }
    }

    return View(model);
}

这也很好,除非用户更改页面然后过滤器处于静止状态.

This also work fine unless the user changed the page then the filters are rest.

这是我的演示班的样子

public class Presenter
{
    public IPagedList<Task> Tasks { get; set; }
    public TasksFiltersViewModel Form { get; set; }
    public int PageNumber { get; set; }
    public IEnumerable<SelectListItem> Statuses { get; set; }
}

我如何允许用户在保留过滤器的同时使用页面?

How can I allow the users to use the pages while keeping the filters?

这是我的过滤器虚拟机

public class TasksFiltersViewModel
{
    public int Status { get; set; }
}

视图看起来像这样

@using (Html.BeginForm("Index", "Tasks", FormMethod.Post, new { @class = "form-horizontal" }))
{
    @Html.AntiForgeryToken()

    <div class="form-group">
        @Html.LabelFor(m => m.Form.Status, new { @class = "control-label col-sm-3" })
        <div class="col-sm-9">
            @Html.DropDownListFor(m => m.Form.Status, Model.Statuses, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.Form.Status, "", new { @class = "text-danger" })
        </div>

    </div>

    <div class="row">
        <div class="col-sm-9 col-md-push-3">
            <div>
                <button type="submit" class="btn btn-default">Filter</button>
            </div>
        </div>
    </div>

}

foreach (var task in Model.Tasks)
{
    <tr>
        <td>@task.Name</td>
        <td>@task.Type</td>
        <td>@Html.ActionLink("Edit", "Details", "Task", new { @id = task.Id }, new { @class = "btn btn-primary btn-sm" })</td>
    </tr>
}


@Html.PagedListPager(Model.Tasks, id => Url.Action("Index", new { id }))

推荐答案

您的表单需要发布回GET方法,并且该方法需要包含过滤器属性的参数.视图中的PagedListPager代码还需要包括那些过滤器属性,以便在导航到下一页/上一页时保留它们.请注意,Index() POST方法未使用,可以删除.

Your form needs to post back to the GET method, and that method needs to include parameters for your filter properties. Your PagedListPager code in the view also need to include those filter properties so they are retained when you navigate to the next/previous page. Note that the Index() POST method is not used and can be deleted.

让模型的过滤器属性包含一个复杂的对象,并在绑定时增加额外的复杂性,因此首先将模型更改为

Having your model contain a complex object to the filter properties and extra complexity when binding, so start by changing your model to

public class Presenter
{
    public IPagedList<Task> Tasks { get; set; }
    public int? Status { get; set; } // note nullable
    ... // add any other properties of TasksFiltersViewModel 
    public int PageNumber { get; set; }
    public IEnumerable<SelectListItem> Statuses { get; set; }
}

然后将Index()方法更改为

public ActionResult Index(int? id, int? status) // add any other parameters your filtering on
{
    int pageNumber = (id ?? 1);
    var tasks = db.Tasks; // IQueryable<Task>
    if (status.HasValue)
    {
        tasks = tasks.Where(x => x.Status == status.Value)
    }
    if (otherParametersHaveValue)
    {
        tasks = tasks.Where(....);
    }
    Presenter model = new Presenter()
    {
        PageNumber = id ?? 1,
        Status = status,
        .... // set any other filter properties from the parameters
        Statuses = new SelectList(...),
        Tasks = tasks.ToPagedList(pageNumber, 30)
    };
    return View(model );
}

并将视图更改为

// Make the form a GET
@using (Html.BeginForm("Index", "Tasks", FormMethod.Get, new { @class = "form-horizontal" }))
{
    ....
    // Modify expression based on revised model properties
    @Html.DropDownListFor(m => m.Status, Model.Statuses, ...)
}
....
// Add filter parameters to url so they are retained
@Html.PagedListPager(Model.Tasks, id => Url.Action("Index", new { id, status = Model.Status })) // add other filter properties as required

这篇关于我如何在Asp.net MVC和实体框架中进行分页时应用过滤器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆