I would like to pass a model and an int
to a controller upon clicking an ActionLink
.
@Html.ActionLink("Next", "Lookup", "User", new { m = Model.UserLookupViewModel, page = Model.UserLookupViewModel.curPage }, null)
Does not work, instead it passes a blank instance of the model, which one would expect when using new
.
@Html.ActionLink("Next", "Lookup", "User", Model.UserLookupViewModel, null)
Does work.
Controller
[HttpGet]
public ActionResult Lookup(UserLookupViewModel m, int page = 0)
{
return this.DoLookup(m, page);
}
View model
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; }
}
How can I pass them together? The Lookup
method's arguments match the named properties in the ActionLink.
HTML Links The easiest way to render an HTML link in is to use the HTML. ActionLink() helper. With MVC, the Html. ActionLink() does not link to a view.
You can't use an ActionLink to pass properties with a Link but you can do the following to get the same behavior.
<form action="/url/to/action" Method="GET"> <input type="hidden" name="Property" value="hello,world" /> <button type="submit">Go To User</button> </form>
If you create a helper to generate these GET forms, you will be able to style them like they are regular link buttons. The only thing I caution against is that ALL forms on the page are susceptible to modification so I wouldn't trust the data. I'd rather just pull the data again when you get to where you are going.
I use the technique above when creating search actions and want to retain a search history and keep the back button working.
Hope this helps,
Khalid :)
P.S.
The reason this works.
@Html.ActionLink("Next", "Lookup", "User", Model.UserLookupViewModel, null)
Is because the parameter list of the ActionLink method is generalized to take an object, so it will take anything. What it will do with that object is pass it to a RouteValueDictionary and then try to create a querystring based on the properties of that object.
If you say that method is working above, you could also just try adding a new property to the viewmodel called Id and it will work like you wanted it to.
You'll have to serialize your model as a JSON string, and send that to your controller to turn into an object.
Here's your actionlink:
@Html.ActionLink("Next", "Lookup", "User", new { JSONModel = Json.Encode(Model.UserLookupViewModel), page = Model.UserLookupViewModel.curPage }, null)
In your controller, you'll need a method to turn your JSON data into a 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;
}
In your ActionResult, you turn the JSON string into an object:
public ActionResult YourAction(string JSONModel, int page)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Model.UserLookupViewModel));
var yourobject = (UserLookupViewModel)ser.ReadObject(GenerateStreamFromString(JSONModel));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With