在pager中回发后模型为空

sve*_*vit 6 c# asp.net-mvc telerik-grid asp.net-mvc-3

在我的页面上,我有:

搜索工作正常 - 我可以输入一些文本或选中过滤器部分中的复选框,并显示相应的结果.

分页工作正常只有在我加载页面时才使用它(这意味着在我点击搜索按钮之前,在这种情况下,网址是'...主页').

但是如果首先单击搜索(在这种情况下,url将变为'... Home/Search')然后尝试转到网格上的另一个页面,那么我在Search方法中得到一个异常,因为model.Filter参数是null(System.NullReferenceException:对象引用未设置为对象的实例.)

我试图以许多不同的方式解决问题(使用RedirectToAction方法,将过滤器存储到会话并在Search方法中使用它,...)但是没有解决方案适用于所有场景.有任何想法吗?

我的简化代码:

HomeController的:

public ActionResult Index()
{
    // On page load display all data without filters.
    var filter = new OverviewFilterModel
    {
        Type1 = true,
        Type2 = true,
        WorkingOrder = ""
    };
    ViewBag.Results = GetResults(filter);
    return View(new HomeModel { Filter = filter });
}

public ActionResult Search(HomeModel model)
{
    ViewBag.Results = GetResults(model.Filter);
    return View("Index");
}

public class OverviewFilterModel
{
    public bool Type1 { get; set; }
    public bool Type2 { get; set; }
    public string WorkingOrder { get; set; }
}

public class HomeModel
{
    public OverviewFilterModel Filter { get; set; }
    public IEnumerable<OverviewResultsModel> Results { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

视图:

<!-- ... -->
@model HomeModel
<!-- ... -->

@using (Html.BeginForm("Search", "Home", FormMethod.Post, new { @class = "form-inline" }))
{
    <div class="form-group" style="margin-left: 135px;">
        @Html.CheckBoxFor(p => p.Filter.Type1)@Html.LabelFor(p => p.Filter.Type1, new { style = "margin: 0 15px 0 5px;" })
    </div>
    <!-- a bunch of other checkboxes -->
    <br />
    <div class="form-group">
        <label style="width: 130px; text-align: right;">Delovni nalog</label>
        @Html.TextBoxFor(p => p.Filter.WorkingOrder, new { @class = "form-control ecert-filter-small", @autocomplete = "off" })
    </div>
    <!-- a bunch of other textboxes -->
    <button class="k-button" id="button-refresh" style="margin: 10px 0 0 135px;">Refresh</button>
    <hr />
    @(Html.Kendo().Grid<OverviewResultsModel>()
        .BindTo((IEnumerable<OverviewResultsModel>)ViewBag.Results)
        .Name("gridOverview")
        .Events(p => p.Change("overviewOnRowSelect"))
        .Columns(columns =>
        {
            columns.Template(@<text>@Html.ActionLink("WorkingOrder", "Index", "WO", new { dn = @item.WorkingOrder }, new { @class = "selectable-dn" })</text>).Title("");
            columns.Bound(p => p.Type);
            columns.Bound(p => p.WorkingOrder);
            columns.Bound(p => p.Date);
            columns.Bound(p => p.ProductId);
            columns.Bound(p => p.ProductName);
        })
        .Selectable()
        .Pageable(p => p
            .Refresh(true)
            .PageSizes(true)
            .ButtonCount(10)
            .Messages(q =>
            {
                q.Display("{0} - {1} od {2} records");
                q.Empty("No data for selected filter");
                q.ItemsPerPage("Number of records per page");
            })
        )
        .DataSource(p => p.Server().PageSize(20).Model(q => { q.Id(r => r.WorkingOrder); }))
    )
}
Run Code Online (Sandbox Code Playgroud)

sve*_*vit 3

我在会话对象的帮助下解决了这个问题 - 一个用于过滤器,一个用于结果。这不是最优雅的解决方案,但它确实有效。

public ActionResult Index()
{
    // On page load display all data without filters.
    OverviewFilterModel filter;
    if (Session["filter"] == null) {
        var filter = new OverviewFilterModel
        {
            Type1 = true,
            Type2 = true,
            WorkingOrder = ""
        };
    }
    else {
        filter = (OverviewFilterModel)Session["filter"];
    }

    if (Session["results"] == null){
        ViewBag.Results = GetResults(filter);
    }
    else{
        ViewBag.Results = Session["results"];
    }

    return View(new HomeModel { Filter = filter });
}

public ActionResult Search(HomeModel model)
{
    if (model.Filter == null)
    {
        model.Filter = (OverviewFilterModel)Session["filter"];
    }

    ViewBag.Results = GetResults(model.Filter);
    return View("Index");
}

private IEnumerable<OverviewResultModel> GetResults(OverviewFilterModel filter){
    var data = ...

    Session["results"] = data;
    Session["filter"] = filter;

    return data;
}
Run Code Online (Sandbox Code Playgroud)