【发布时间】:2016-10-18 13:52:50
【问题描述】:
我正在 MVC 中制作一个简单的 搜索 页面,其中包含一些过滤器。过滤器由我的 ViewModel 中的属性表示。我的 ViewModel 绑定到 cshtml 中的 GET 表单,因此我的过滤器将出现在查询字符串中,并且用户将能够为他的搜索添加书签。
我想做的是为我的一些过滤器分配一个默认值。
我的(简化的)视图模型:
public class SearchViewModel
{
//Filter I want to set a default value to
public OrganizationType? OrganizationType {get; set;}
//Results of the search
public IEnumerable<ItemViewModel> Items {get; set;}
}
我想为 OrganizationType 设置一个默认值。我不能简单地在 SearchViewModel 的构造函数中设置它,因为它取决于当前用户:
public void InitViewModel(SearchViewModel vm)
{
vm.OrganizationType = _someLogic.GetDefaultValue(_currentUser);
}
第一个解决方案是简单地检查 OrganizationType 是否为空,然后分配一个默认值:
public ActionResult Search(SearchViewModel vm)
{
if(vm.OrganizationType == null)
vm.OrganizationType = _someLogic.GetDefaultValue(_currentUser);
return View(vm);
}
但此解决方案不起作用,因为 null 值对应于空过滤器,这是用户可以做出的选择。所以我不能覆盖它。
我尝试的第二个解决方案是在 Search 操作中指定控制器的默认值应为 null:
public ActionResult Search(SearchViewModel vm = null)
{
if (vm == null)
{
vm = new SearchViewModel();
InitViewModel(vm);
}
...
return View(vm);
}
但实际上,变量 vm 永远不会为空,因此永远不会设置默认值。
我还尝试了两个动作,一个没有 ViewModel,我用默认值实例化一个新的 ViewModel,然后调用第二个动作:
public ActionResult Search()
{
var vm = new SearchViewModel();
InitViewModel(vm);
//Simply call the second action with the initizalied ViewModel
return Search(vm);
}
public ActionResult Search(SearchViewModel vm)
{
...
return View(vm);
}
但它不起作用,因为现在这两个动作之间存在歧义,asp.net 不知道该选择哪一个。
总之,我想找到一种方法来为 ViewModel 设置默认值,而不是在构造函数中设置它并覆盖用户选择。
换一种说法,我如何区分“空”视图模型和一些值从表单绑定的视图模型。
有什么想法吗?
【问题讨论】:
-
为什么不能使用
_currentUser? -
@markpsmith,_currentUser 是我的控制器的成员变量,它依赖于当前的 HttpContext。我可以在我的控制器中使用它,但我不能在 ViewModel 构造函数中使用它,因为我没有从那里访问 HttpContext 的干净方法。
-
假设你使用的是 MVC5 和 C#5,你可以试试这个吗?公共组织类型?组织类型 {get;设置;} = null; //或者你想设置为默认值的任何值
-
@PratikGaikwad 问题是我无法轻松设置 OrganizationType 的默认值,我需要当前用户,然后我向我的数据库发出请求以检索当前的默认 OrganizationType用户(可以为空)。
-
OrganizationType是枚举吗?如果您可以更改它,为什么不添加一个None值,例如-1,它表示当用户未进行选择时提交的值。因此,第一次加载页面时,您实际上可以检查OrganizationType是否为空,然后默认它。否则,None表示没有选择。
标签: asp.net asp.net-mvc