如何使用视图模型的属性创建ActionLink

Dav*_*haw 6 asp.net-mvc actionlink model-binding asp.net-mvc-3

我有一个带有Filter属性的ViewModel,它具有许多我用来过滤数据的属性

例:

class MyViewModel : IHasFilter
{
     public MyData[] Data { get; set; }
     public FilterViewModel Filter { get; set; }
}

class FilterViewModel
{
    public String MessageFilter { get; set; }
    //etc.
}
Run Code Online (Sandbox Code Playgroud)

这在使用我的视图时工作正常.我可以设置属性,Model.Filter并将它们传递给Controller.我现在要做的是创建一个ActionLink具有与上述格式一起使用的查询字符串.

我的View从上面生成的查询字符串如下所示:

http://localhost:51050/?Filter.MessageFilter=Stuff&Filter.OtherProp=MoreStuff
Run Code Online (Sandbox Code Playgroud)

我需要在网格中每行进入上面视图的不同视图中生成一个ActionLink.

我试过了:

Html.ActionLink(
    item.Message,
    "Index",
    "Home",
    new { Filter = new { MessageFilter = item.Message, }, },
    null);
Run Code Online (Sandbox Code Playgroud)

我也尝试将routeValues参数设置为:

new MyViewModel { Filter = new FilterViewModel { MessageFilter = item.Message, }, },
Run Code Online (Sandbox Code Playgroud)

但是这些不会像上面那样生成查询字符串.

And*_*tan 1

您可以从一个FilterViewModel实例创建一个 RouteValueDictionary,然后使用ToDictionary它来传递到另一个 RouteValues,其中所有键都以 为前缀'Filter.'

更进一步,您可以构造一个特殊的重写,它RouteValueDictionary接受一个前缀(因此使其对于其他场景更有用):

public class PrefixedRouteValueDictionary : RouteValueDictionary
{
  public PrefixedRouteValueDictionary(string prefix, object o)
    : this(prefix, new RouteValueDictionary(o))
  { }

  public PrefixedRouteValueDictionary(string prefix, IDictionary<string, object> d)
    : base(d.ToDictionary(kvp=>(prefix ?? "") + kvp.Key, kvp => kvp.Value))
  { }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以执行以下操作:

Html.ActionLink( 
  item.Message, 
  "Index", 
  "Home", 
  new PrefixedRouteValueDictionary("Filter.", 
    new FilterViewModel() { MessageFilter = item.Message }), 
  null); 
Run Code Online (Sandbox Code Playgroud)

但需要注意的是Add, 、RemoveTryGetValuethis[string key]方法不会更改以考虑prefix. 这可以通过定义这些方法的版本来实现new,但因为它们不是虚拟的,所以它们只能从知道他们正在与 aPrefixedRouteValueDictionary而不是 a进行对话的调用者那里工作RouteValueDictionary