这是我的模特:
public class IndexViewModel
{
public FilterConditions conditions { get; set }
public IEnumerable<SelectListItem> Countries { get; set }
}
public class FilterConditions
{
public string condition11 { get; set }
// ...
}
我有一个Index
动作方法,如下所示:
public ActionResult Index()
{
var model = new IndexViewModel();
// fill the model here with default values
return View(model);
}
视图呈现一个带有filterconditions作为输入类型的表单。
现在我希望通过此操作方法处理该表单中的帖子:
[HttpPost]
public ActionResult Index(FilterConditions model)
{
// do some magic with model and return another view here
}
这实际上有效(我在方法中设置断点,然后调用它),但我的模型的属性总是为空(默认值),而它们应该包含表单发布的值。 / p>
当我修改这样的动作方法时:
[HttpPost]
public ActionResult Index(IndexViewModel model)
{
// do some magic with model.conditions and return another view here
}
一切都像它应该的那样,但这不是“正确的”(恕我直言),因为我不需要回国时的'国家'名单,我只需要选定的国家(这是其中一个条件)。
在不必将整个原始viewmodel作为输入参数的情况下,使这项工作成为一种很好的(最佳实践)方法是什么?
顺便说一下,我正在使用ASP.NET MVC 2(我认为这不重要,因为我认为它在MVC 3中是同样的问题,但我并不完全确定。)
(我一直在互联网上寻找关于asp.net mvc中的下拉列表和视图模型的“最佳实践”,但我发现的不同建议并没有真正相互排列,而且很多已经过时了我没有找到一个“官方”的最佳实践。我希望我朝着正确的方向前进(将列表作为我的视图模型的一部分),如果我不是,请随时纠正我。如果你知道的话,也可以随时指出“认可的最佳实践”。)
更新:
我发现我可以将[Bind]属性与“filterconditions”的前缀一起使用。这确实适用于这种观点。但我原来的问题(我承认,它没有包括在我的问题中)没有解决。
碰巧这个特定的动作方法也是从另一个视图调用的(它是一个ajax调用),它没有那个前缀,在这种情况下它现在不再起作用了。有什么建议吗?
答案 0 :(得分:4)
我找到了解决方案。
显然,当我为参数变量使用相同的名称作为类型的名称(大小写不必匹配)时,如下所示:
[HttpPost]
public ActionResult Index(FilterConditions filterConditions)
{
// do some magic with model and return another view here
// now the filterConditions variable actually contains values!
}
一切都像它应该的那样(我的filterConditions的值不再为空/ null)。显然,默认的模型绑定器使用参数的名称作为绑定的潜在前缀。
我很高兴我发现了,但如果在某处更清楚地记录下来会更好。这根本不明显。
修改强>: 根据要求:这是我视图中的代码(aspx):
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyProject.Models.IndexViewModel>" %>
<%-- ... more stuff here ... --%>
<% using (Html.BeginForm())
{%>
<%= Html.ValidationSummary(true)%>
<fieldset>
<div class="editor-label">
<%= Html.LabelFor(model => model.FilterConditions.Country)%>
</div>
<div class="editor-field">
<%= Html.DropDownListFor(model => model.FilterConditions.Country, Model.Countries)%>
<%= Html.ValidationMessageFor(model => model.FilterConditions.Country)%>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.FilterConditions.Make)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.FilterConditions.Make)%>
<%= Html.ValidationMessageFor(model => model.FilterConditions.Make)%>
</div>
<%-- ... more fields inserted here ... --%>
<p>
<input type="submit" value=" Search... " />
</p>
</fieldset>
<% } %>
答案 1 :(得分:1)
嗨fretje:现在我可以用你的方式来解决你的问题,首先我有两个模型“IndexViewModel”&amp; “Index”和DropDownList(没关系,只提供DropDown项目):
public class IndexViewModel : Index
{
//public int value { get; set; }
public List<System.Web.Mvc.SelectListItem> items { get; set; }
}
public class Index
{
public int value { get; set; }
}
class DropDownList
{
public List<System.Web.Mvc.SelectListItem> GetDropDownList()
{
List<System.Web.Mvc.SelectListItem> result = new List<System.Web.Mvc.SelectListItem>();
result.Add(new System.Web.Mvc.SelectListItem
{
Value = "1",
Text = "Apple"
});
result.Add(new System.Web.Mvc.SelectListItem
{
Value = "2",
Text = "Milk"
});
return result;
}
}
两个控制器是Test()和Test(Models.Index),我传递了IndexViewModel并回发了IndexModel:
public ActionResult Test()
{
var result =
new Models.IndexViewModel
{
value = 1,
items = new Models.DropDownList().GetDropDownList()
};
return View(result);
}
[HttpPost]
public ActionResult Test(Models.Index posatback)
{
return View();
}
测试视图()是:
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-field">
<%: Html.DropDownListFor(m=>m.value, Model.items )%>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
这是工作!谢谢fretje,我学到了另外一项技术。 :)
也许你可以试试
[HttpPost]
public ActionResult Index([Bind(Exclude="Countries")]IndexViewModel model)
{
// do some magic with model.conditions and return another view here
}
您好〜 您不需要将整个SelectListItem组合到ViewModel,实际上您的ViewModel只有一个字段来存储用户的选择,整数或字符串,然后使用DropDownListFor,如:
<%: Html.DropDownListFor(item.WeaponID, MyApplication.Models.DropDownList.GetDropDownList() )%>
请在我的blogspot中查看我的帖子,我用一个非常简单的例子来解释: http://maidot.blogspot.com/2011/04/aspnet-mvc-viewdropdownlistfor.html
如果您有任何问题,请告诉我们。)