ASP.NET MVC通过ActionLink传递模型

Lee*_*Lee 22 asp.net asp.net-mvc

我想int点击一个模型和一个控制器ActionLink.

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

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

@Html.ActionLink("Next", "Lookup", "User", Model.UserLookupViewModel, null)
Run Code Online (Sandbox Code Playgroud)

有用吗

调节器

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

查看模型

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; }
}
Run Code Online (Sandbox Code Playgroud)

我怎么能把它们放在一起?该Lookup方法的参数匹配在ActionLink的命名属性.

Kha*_*meh 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>
Run Code Online (Sandbox Code Playgroud)

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

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

希望这可以帮助,

哈立德:)


PS

这是有效的原因.

@Html.ActionLink("Next", "Lookup", "User", Model.UserLookupViewModel, null)
Run Code Online (Sandbox Code Playgroud)

是因为ActionLink方法的参数列表被概括为接受一个对象,所以它将需要任何东西.它将对该对象执行的操作是将其传递给RouteValueDictionary,然后尝试基于该对象的属性创建查询字符串.

如果你说方法在上面工作,你也可以尝试向名为Id的viewmodel添加一个新属性,它会像你想要的那样工作.


JKS*_*S77 11

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

这是你的actionlink:

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

在您的控制器中,您需要一种方法将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;
}
Run Code Online (Sandbox Code Playgroud)

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

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


Rob*_*ert 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)
Run Code Online (Sandbox Code Playgroud)

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" />
  }
Run Code Online (Sandbox Code Playgroud)

如果需要,您可以在页面上拥有多种这些类型的表单.

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

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