我有一个 SearchViewModel:
public class SearchViewModel
{
[Required]
public DateTime From { get; set; }
[Required]
public int Days { get; set; }
public long DealerID { get; set; }
public IQueryable<TypesAvail> TypesAvails { get; set; }
}
IQueryable TypesAvails 是另一个类,它包含可从 DealerID 以及 SearchviewModel 类的 From 和 Days 属性之间获得的 CarTypes 列表 - 它还用于在视图中生成下拉列表:
public class TypesAvail
{
public String TypeNme { get; set; }
public long TypeID { get; set; }
public int NumSelected { get; set; }
public int TypeCount { get; set; }
public IEnumerable<SelectListItem> CarsAvail
{
get
{
return new SelectList(
Enumerable.Range(0, TypeCount+1)
.OrderBy(typecount => typecount)
.Select(typecount => new SelectListItem
{
Value = typecount.ToString(),
Text = typecount.ToString()
}), "Value", "Text");
}
}
}
我的控制器是:(编辑:添加控制器以显示访问数据的代码)
public ActionResult Avail(SearchViewModel model, string id)
{
if (ModelState.IsValid)
{
var dteFrom = model.From;
var dteTo = model.From.AddDays(model.Days);
var prebookedCars = db.Cars
.Where(car=> car.Rentals.Any(rental =>
(model.DealerID == rental.Dealerid) && (
(dteFrom >= rental.dateout && dteFrom < rental.datein )
||
(dteTo > rental.dateout && dteTo <= rental.datein )
||
(dteFrom <= rental.dateout && dteTo >= rental.datein )
)));
model.TypesAvails = db.Cars
.Where(r => r.Dealerid == model.DealerID)
.Except(prebookedCars)
.GroupBy(p => p.CarType)
.Select(g => new TypesAvail
{
TypeNme = g.Key.type_name,
TypeID = g.Key.type_id,
TypeCount = g.Count(),
NumSelected = 0
}
);
return View(model);
}
else
{
return View(model);
}
}
逻辑(我有待纠正)如下:
- SearchViewModel 针对 TypesAvail 发送到带有 null 的视图
当 Post 发生时,控制器将 From、Days 和 DealerID 直接填充回模型中,使用:
[HttpPost]
public ActionResult Avail(SearchViewModel model)
在控制器中,它还会填充 TypesAvail IQueryable
因此,现在 ViewModel 具有搜索日期、天数和 TypesAvailable 列表,其中包括选择列表。
这在视图中重新填充,如下所示:
@model ebm2.ViewModels.SearchViewModel
@using (Html.BeginForm())
{
@Html.ValidationSummary()
<ul data-role="listview" data-inset="true">
<li data-role="list-divider">Check Availability</li>
<li data-role="fieldcontain">
@Html.LabelFor(m => m.From)
@Html.TextBoxFor(m => m.From, new { @type = "date", data_role = "datebox", data_options = "{\"mode\":\"slidebox\", \"overrideDateFormat\":\"%A %d %b %Y\"}" })
@Html.ValidationMessageFor(m => m.From)
</li>
<li data-role="fieldcontain">
@Html.LabelFor(m => m.Days)
@Html.TextBoxFor(m => m.Days, new { @type = "range", min = 1, max = 30 })
@Html.ValidationMessageFor(m => m.Days)
</li>
<li data-role="fieldcontain">
<input type="submit" value="Search" />
</li>
</ul>
@Html.HiddenFor(m => m.DealerID)
if (Model.TypesAvails != null)
{
<ul data-role="listview" data-inset="true">
<li data-role="list-divider">Book</li>
@foreach (var item in Model.TypesAvails)
{
<li data-role="fieldcontain">
@Html.HiddenFor(modelItem => item.TypeID) ->
@Html.DisplayFor(modelItem => item.NumSelected) ->
@Html.DropDownListFor(modelItem => item.NumSelected, item.CarsAvail)
</li>
}
</ul>
}
}
返回服务器的第二个 POST 显示:
From=07%2F08%2F2012+00%3A00%3A00& Nights=1 & DealerID=1 &
item.TypeID=3059 & item.NumSelected=3 &
item.TypeID=3103 & item.NumSelected=2 &
item.TypeID=3170 & item.NumSelected=7 &
item.TypeID=3212 & item.NumSelected=4
显示这些的 Razor 并没有将 TypeID 分配给每个下拉列表:
@Html.HiddenFor(modelItem => item.TypeID)
@Html.DropDownListFor(modelItem => item.NumSelected, item.CarsAvail)
我的问题来自 POST 模型 - TypesAvail 显示为 NULL - 有没有办法在回发时直接进入 ViewModel 中表示下拉列表中的选定项目?
如果没有,我如何遍历 FORM 字段,以创建另一个模型 - 它将具有:
From
Days
DealerID
{
TypeID = 3059, NumSelected = 3,
TypeID = 3103, NumSelected = 2,
TypeID = 3170, NumSelected = 7,
TypeID = 3212, NumSelected = 4
}
...然后我可以用来将记录添加到我的数据库(基本上是经销商想要在两个日期之间租用的汽车列表)。
或者我是否试图从一个表单中获取搜索日期,然后用多个下拉列表填充同一个表单,做太多事情 - 有没有更好的方法:
- 从日期框和晚数搜索
- 然后显示符合搜索条件的选项列表
- 然后发布到服务器,并保存搜索数据(从日期、天数、dealerID),以及选择的下拉列表,以及在每个列表中选择了什么?
谢谢你,马克
更新
在 Shyu 的帮助下,我取得了一些进展——我添加了一个编辑器模板:
@model ebm2.Models.TypesAvail
@Html.DropDownListFor(modelItem => modelItem.NumSelected, Model.CarsAvail)
...并在视图中呈现:
@Html.EditorFor(model=>model.TypesAvails)
但是,当我将表单发布回控制器(添加 editorTemplate 之后)时,我收到以下消息:
[MissingMethodException: Cannot create an instance of an interface.]
我假设这意味着它不再识别模型 - 这是因为 EditorTemplate 吗?
是我的回发方法,然后将其添加到 ViewModel 是最好的方法吗,或者您是否建议使用 jQuery/Ajax 在客户端完成所有操作 - 并且只有在我完成 JSON 时才最终回发到服务器我的模型的对象?
我很感激这方面的任何指导。
谢谢,马克