ASP.NET MVC通过ActionLink传递模型

时间:2014-02-03 13:48:37

标签: asp.net asp.net-mvc

点击int后,我想将模型和ActionLink传递给控制器​​。

@Html.ActionLink("Next", "Lookup", "User", new { m = Model.UserLookupViewModel, page = Model.UserLookupViewModel.curPage }, null)

不起作用,而是传递模型的空白实例,使用new时可以预期。

@Html.ActionLink("Next", "Lookup", "User", Model.UserLookupViewModel, null)

是否有效。

控制器

[HttpGet]
public ActionResult Lookup(UserLookupViewModel m, int page = 0)
{
    return this.DoLookup(m, page);
}

查看模型

public class UserLookupViewModel
{
    public int curPage { get; set; }

    [Display(Name = "Forenames")]
    public string Forenames { get; set; }

    [Display(Name = "Surname")]
    public string Surname { get; set; }

    [Display(Name = "DOB")]
    public DateTime? DoB { get; set; }

    [Display(Name = "Post code")]
    public string Postcode { get; set; }
}

如何将它们一起传递? Lookup方法的参数与ActionLink中的命名属性匹配。

4 个答案:

答案 0 :(得分:13)

您不能使用ActionLink通过链接传递属性,但您可以执行以下操作以获得相同的行为。

<form action="/url/to/action" Method="GET">
  <input type="hidden" name="Property" value="hello,world" />
  <button type="submit">Go To User</button>
</form>

如果您创建一个帮助程序来生成这些 GET 表单,您将能够像定期链接按钮一样设置样式。我唯一要注意的是页面上的 ALL 表单很容易被修改,所以我不相信这些数据。当你到达目的地时,我宁愿再次提取数据。

我在创建搜索操作时使用上述技术,并希望保留搜索记录并保持后退按钮正常工作。

希望这有帮助,

哈立德:)


P.S。

这是有效的原因。

@Html.ActionLink("Next", "Lookup", "User", Model.UserLookupViewModel, null)

因为ActionLink方法的参数列表被推广为采用对象,所以它将需要任何东西。它对该对象的作用是将它传递给 RouteValueDictionary ,然后尝试根据该对象的属性创建一个查询字符串。

如果你说这个方法在上面工作,你也可以尝试在名为 Id 的视图模型中添加一个新属性,它会像你想要的那样工作。

答案 1 :(得分:10)

您必须将模型序列化为JSON字符串,然后将其发送到控制器以变成对象。

这是你的actionlink:

@Html.ActionLink("Next", "Lookup", "User", new { JSONModel = Json.Encode(Model.UserLookupViewModel), page = Model.UserLookupViewModel.curPage }, null)

在您的控制器中,您需要一种方法将JSON数据转换为MemoryStream:

private Stream GenerateStreamFromString(string s)
{
  MemoryStream stream = new MemoryStream();
  StreamWriter writer = new StreamWriter(stream);
  writer.Write(s);
  writer.Flush();
  stream.Position = 0;
  return stream;
}

在ActionResult中,将JSON字符串转换为对象:

public ActionResult YourAction(string JSONModel, int page)
{
  DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Model.UserLookupViewModel));
  var yourobject =  (UserLookupViewModel)ser.ReadObject(GenerateStreamFromString(JSONModel));
}

答案 2 :(得分:5)

虽然我强烈建议您使用表单来完成您为了安全起见而尝试执行的操作。

 @Html.ActionLink("Next", "Lookup", "User", new 
      { Forenames = Model.UserLookupViewModel.Forenames, 
        Surname = Model.UserLookupViewModel.Surname, 
        DOB = Model.UserLookupViewModel.DOB,  
        PostCode = Model.UserLookupViewModel.PostCode, 
        page = Model.UserLookupViewModel.curPage }, null)

MVC将适当地映射属性;但是,这将使用您的URL将值传递给控制器​​。这将显示所有世界的值。

我强烈建议使用表单以保证安全,特别是在处理敏感数据(如DOB)时。

我个人会做这样的事情:

 @using (Html.BeginForm("Lookup", "User")
 {
     @Html.HiddenFor(x => x.Forenames)
     @Html.HiddenFor(x => x.Surname)
     @Html.HiddenFor(x => x.DOB)
     @Html.HiddenFor(x => x.PostCode)
     @Html.HiddenFor(x => x.curPage)

     <input type="submit" value="Next" />
  }

如果需要,您可以在页面上使用多种类型的表单。

您的控制器接受一个帖子,但功能相同:

 [HttpPost]
 public ActionResult Lookup(UserLookupViewModel m, int page = 0)
 {
     return this.DoLookup(m, page);
 }

答案 3 :(得分:0)

请尝试以下解决方案:

@{
var routeValueDictionary = new RouteValueDictionary("");
routeValueDictionary.Add("Forenames",Forenames);
routeValueDictionary.Add("Surname",Surname);
routeValueDictionary.Add("DoB ",DoB );
routeValueDictionary.Add("Postcode",Postcode );
routeValueDictionary.Add("Page",PageNum );
// Add any item you want!
}
@html.ActionLink("LinkName", "ActionName", "ControllerName",
routeValueDictionary , new{@class="form-control"})