我有一个带有Razor视图的.NET MVC项目,我想实现包含下拉列表,文本框和搜索按钮的搜索功能。
问题在于,我希望在@RenderBody()
调用的_Layout.cshtml文件外部中实现此搜索代码段。这意味着可以在每个页面上访问搜索功能(它将位于最右上角)。
我正在努力找出实现这一目标的好方法。我可以让它工作,但它将涉及向所有控制器和操作添加相同的代码(获取下拉值)。
ViewBag.States = new SelectList(db.States, "Id", "Name");
有没有更好的方法来实现这个?这样做感觉非常重复。
答案 0 :(得分:3)
您可以使用子操作方法返回标题所需的局部视图,并在布局中调用此操作方法。
为所需属性创建视图模型。
public class AllPageVm
{
public int SelectedItem { set; get; }
public List<SelectListItem> Items { set; get; }
}
现在在您的任何控制器中创建一个操作方法。使用ChildActionOnly
装饰器标记此操作方法。
public class HomeController : Controller
{
[ChildActionOnly]
public ActionResult HeaderSearch()
{
var vm = new AllPageVm()
{
Items = db.States
.Select(a => new SelectListItem() {Value = a.Id.ToString(),
Text = a.Name})
.ToList()
};
return PartialView(vm);
}
现在,在HeaderSearch.cshtml
局部视图中,您可以为搜索标题呈现所需的标记。这是一个渲染下拉列表的简单示例。您可以更新此部分以包含您想要的任何标记(例如:具有文本框,下拉列表和按钮等的表单标记)
@model AllPageVm
<div>
<label>Select one state</label>
@Html.DropDownListFor(a => a.SelectedItem, Model.Items, "Select")
</div>
现在,在您的布局中,您可以调用此子操作方法
<div class="container body-content">
@Html.Action("HeaderSearch", "Home")
@RenderBody()
<hr/>
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
确保从HeaderSearch子操作方法而不是View方法调用PartialView
方法。如果调用View方法,它将递归调用相同的方法,您将获得StackOverflow异常