ASP.NET MVC Passing models by ActionLink
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));
}
While I highly suggest you use a form to accomplish what your attempting to do here for security sake.
@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 will map the properties appropriately doing this; however, this will use your url to pass the values to the controller. This will display the values for all the world to see.
I highly suggest using a form for security sake especially when dealing with sensitive data such as DOB.
I personally would do something like this:
@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" />
}
You can have multiple of these type of forms on the page if needed.
Your controller then accepts a post but functions the same way:
[HttpPost]
public ActionResult Lookup(UserLookupViewModel m, int page = 0)
{
return this.DoLookup(m, page);
}
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.