继之前的帖子:Adding a search form using a DateTime template
...但是我没有按照上一篇文章的回答中的建议使用ViewModel。
我正在尝试帮助进行搜索,根据ViewModel:
进行两个日期(从/到)public class SearchViewModel
{
[Required]
public DateTime From { get; set; }
[Required]
public DateTime To { get; set; }
}
我的意见/搜索/ Index.cshtml是:
@model ttp.Models.SearchViewModel
@{
ViewBag.Title = "Search Availability";
}
<h2>Search Availability</h2>
@using (Html.BeginForm())
{
<div class="row">
<div class="span2">@Html.LabelFor(x => x.From)</div>
<div class="span2">@Html.EditorFor(x => x.From)</div>
<div class="span2">@Html.ValidationMessageFor(x => x.From)</div>
</div>
<div class="row">
<div class="span2">@Html.LabelFor(x => x.To)</div>
<div class="span2">@Html.EditorFor(x => x.To)</div>
<div class="span2">@Html.ValidationMessageFor(x => x.To)</div>
</div>
<div class="row">
<div class="span2 offset2"><button type="submit">Search</button></div>
</div>
}
Get:/ Search / Index控制器是:
//
// GET: /Search/
public ActionResult Index()
{
SearchViewModel svm = new SearchViewModel();
svm.From = DateTime.Today;
svm.To = DateTime.Today;
return View(svm);
}
到目前为止一直很好 - 我的视图显示了日期默认为今天的文本框(使用DateTime Helper)。当我单击“搜索”时,代码将转到SearchController // Post:/ Search,如下所示:
//
// Post: /Search/
[HttpPost]
public ActionResult Index(SearchViewModel searchViewModel)
{
if (!ModelState.IsValid)
{
// Not valid, so just return the search boxes again
return View(searchViewModel);
}
// Get the From/To of the searchViewModel
DateTime dteFrom = searchViewModel.From;
DateTime dteto = searchViewModel.To;
// Query the database using the posted from/to dates
IQueryable<Room> rooms = db.Rooms.Where(r => r.Clients.Any(c => c.Departure >= dteFrom && c.Departure < dteTo));
// This is where I'm unsure
ViewBag.Rooms = rooms.ToList();
return View(rooms.ToList());
}
我现在不确定的是Post控制器的最后几行 - 如何返回IQueryable房间的房间列表 - 并在屏幕上显示房间列表?我是否重定向到另一个视图(如果是这样,我如何将房间列表传递给该视图)?如果我只是尝试运行上面的代码,我会收到错误:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[ttp.Models.Room]', but this dictionary requires a model item of type 'ttp.Models.SearchViewModel'.
我是否尝试混合苹果和梨 - 无论如何在“从”和“到”搜索框(ViewModel)下显示房间列表?
谢谢,
标记
答案 0 :(得分:4)
您可以返回包含搜索结果的其他视图:
IQueryable<Room> rooms = db.Rooms.Where(r => r.Clients.Any(c => c.Departure >= dteFrom && c.Departure < dteTo));
return View("Result", rooms.ToList());
在Result.cshtml
内:
@model IEnumerable<Room>
... show the rooms here
如果您想要保持不同的视图,请修改您的视图模型,使其包含第三个属性,该属性将代表您将在POST控制器操作中填充的搜索结果(一组房间)并重新显示相同的视图:
IQueryable<Room> rooms = db.Rooms.Where(r => r.Clients.Any(c => c.Departure >= dteFrom && c.Departure < dteTo));
searchViewModel.Rooms = rooms;
return View(searchViewModel);
然后在视图中你可以有一个部分来显示结果:
@if (Model.Rooms != null)
{
... display the search results here
}
但在这两种情况下我都认为Room
对象是域模型。良好实践要求您应定义一个视图模型,其中只包含您的视图所需的信息:
public class RoomViewModel
{
... only properties that you need to work with on the view
}
然后使用IEnumerable<RoomViewModel> Rooms { get; set; }
属性。您仍然可以从DAL层获取控制器操作中的IQueryable<Room>
域模型,但在将其传递给视图之前,请确保执行到视图模型的转换。这是AutoMapper可以派上用场的地方。
答案 1 :(得分:1)
您正在将不同的模型返回到同一视图,因此首先只需更改控制器以返回传入的searchViewModel
。
ViewBag.Rooms = rooms.ToList();
return View(searchViewModel);
您也可以将房间列表返回到同一视图,就像使用ViewBag一样,您在视图中没有任何地方可以呈现列表的任何标记:
@model ttp.Models.SearchViewModel
@{
ViewBag.Title = "Search Availability";
}
<h2>Search Availability</h2>
@using (Html.BeginForm())
{
<div class="row">
<div class="span2">@Html.LabelFor(x => x.From)</div>
<div class="span2">@Html.EditorFor(x => x.From)</div>
<div class="span2">@Html.ValidationMessageFor(x => x.From)</div>
</div>
<div class="row">
<div class="span2">@Html.LabelFor(x => x.To)</div>
<div class="span2">@Html.EditorFor(x => x.To)</div>
<div class="span2">@Html.ValidationMessageFor(x => x.To)</div>
</div>
<div class="row">
<div class="span2 offset2"><button type="submit">Search</button></div>
</div>
}
@if (ViewBag.Rooms != null)
{
foreach (var room in ViewBag.Rooms as List<Room>)
{
// Build your room list markup here
}
}