在寻呼机中回发后模型为空
Model is null after postback in pager
在我的页面上我有:
- 一个 'filter' 部分 - 几个复选框和文本框,
- 一个'search'按钮,
- 带有显示结果的分页的网格。网格来自 Telerik (http://demos.telerik.com/aspnet-mvc/grid/index1),但我认为这不重要。
搜索正常 - 我可以输入一些文本或选中过滤器部分中的复选框,然后会显示相应的结果。
只有当我在加载页面时使用它时分页才能正常工作(这意味着在我单击“搜索”按钮之前,在这种情况下 url 是“...Home”)。
但是如果先点击搜索(在这种情况下 url 将变为 '...Home/Search')然后尝试转到网格上的另一个页面,那么我会得到一个异常Search 方法,因为 model.Filter 参数为空(System.NullReferenceException:对象引用未设置为对象的实例。)
我尝试以多种不同的方式解决问题(使用 RedirectToAction 方法、将过滤器存储到会话并在 Search 方法中使用它,...)但没有一种解决方案适用于所有情况。有什么想法吗?
我的简化代码:
家庭控制器:
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; }
}
查看:
<!-- ... -->
@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); }))
)
}
可能这种方式有助于在执行 GetResults(model.Filter)
:
之前在 Search 方法中处理 HomeModel.Filter 的空值
public ActionResult Search(HomeModel model)
{
if (model.Filter == null)
{
model.Filter = new OverviewFilterModel
{
Type1 = true,
Type2 = true,
WorkingOrder = ""
};
}
ViewBag.Results = GetResults(model.Filter);
return View("Index", new HomeModel { Filter = filter });
}
我只是想 null 值应该由 if 条件处理以防止 NRE,CMIIW。
我在会话对象的帮助下解决了这个问题——一个用于过滤器,一个用于结果。不是最优雅的解决方案,但它有效。
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;
}
在我的页面上我有:
- 一个 'filter' 部分 - 几个复选框和文本框,
- 一个'search'按钮,
- 带有显示结果的分页的网格。网格来自 Telerik (http://demos.telerik.com/aspnet-mvc/grid/index1),但我认为这不重要。
搜索正常 - 我可以输入一些文本或选中过滤器部分中的复选框,然后会显示相应的结果。
只有当我在加载页面时使用它时分页才能正常工作(这意味着在我单击“搜索”按钮之前,在这种情况下 url 是“...Home”)。
但是如果先点击搜索(在这种情况下 url 将变为 '...Home/Search')然后尝试转到网格上的另一个页面,那么我会得到一个异常Search 方法,因为 model.Filter 参数为空(System.NullReferenceException:对象引用未设置为对象的实例。)
我尝试以多种不同的方式解决问题(使用 RedirectToAction 方法、将过滤器存储到会话并在 Search 方法中使用它,...)但没有一种解决方案适用于所有情况。有什么想法吗?
我的简化代码:
家庭控制器:
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; }
}
查看:
<!-- ... -->
@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); }))
)
}
可能这种方式有助于在执行 GetResults(model.Filter)
:
public ActionResult Search(HomeModel model)
{
if (model.Filter == null)
{
model.Filter = new OverviewFilterModel
{
Type1 = true,
Type2 = true,
WorkingOrder = ""
};
}
ViewBag.Results = GetResults(model.Filter);
return View("Index", new HomeModel { Filter = filter });
}
我只是想 null 值应该由 if 条件处理以防止 NRE,CMIIW。
我在会话对象的帮助下解决了这个问题——一个用于过滤器,一个用于结果。不是最优雅的解决方案,但它有效。
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;
}