Reputation: 4257
In my controller I do have this endpoint:
async Task<FileResult> DownloadSelection(AssignedDatabaseSelection selection)
And my HTML looks like:
@if (Model.AssignedDatabaseSelections.Any())
{
<table>
@foreach (var selection in Model.AssignedDatabaseSelections)
{
<tr>
<td>@selection.DisplayName</td>
<td width="10%">
@Html.ActionLink(Strings.CsvLabel, "DownloadSelection", "Home", selection, null)
</td>
</tr>
}
</table>
}
Now I wanted to add another parameter to my controller method:
async Task<FileResult> DownloadSelection(AssignedDatabaseSelection selection, DownloadFormat format)
And
@if (Model.AssignedDatabaseSelections.Any())
{
<table>
@foreach (var selection in Model.AssignedDatabaseSelections)
{
<tr>
<td>@selection.DisplayName</td>
<td width="10%">
@Html.ActionLink(Strings.CsvLabel, "DownloadSelection", "Home", new {selection = selection, Format = DownloadFormat.CSV}, null)
</td>
<td width="10%">
@Html.ActionLink(Strings.ExcelLabel, "DownloadSelection", "Home", new { selection = selection, Format = DownloadFormat.CSV }, null)
</td>
</tr>
}
</table>
}
When I make an inspect elements I got this:
<a href="/Home/DownloadSelection?selection=System.Data.Entity.DynamicProxies.AssignedDatabaseSele_D02B1D7B1220921CC4150FAA016EB8BFD5692B52C49949B0ECB80AA2F98E7355&Format=CSV">Excel</a>
Now, the format is filled, but the selection is always null. What am I missing?
Upvotes: 0
Views: 327
Reputation:
In you first example, the 3rd parameter is a complex object (typeof AssignedDatabaseSelections
) and the method will correctly serialize each property of your object to a query string. Note that it only works because your object contains only simple properties.
In the second example, your creating a new object containing a complex object. The ActionLink()
method (and all methods that generate route/query string values) call the .ToString()
method on each property in the object (hence you get the name of the class) and do not do recursion.
If you want to pass back all properties of the AssignedDatabaseSelections
object plus another property, you need to generate a new object containing each property of AssignedDatabaseSelections
, for example (assuming it contains properties ID
and Name
)
@Html.ActionLink(Strings.CsvLabel, "DownloadSelection", "Home",
new { ID = selection.ID, Name = selection.Name, ......, Format = DownloadFormat.CSV }, null)
Note that if AssignedDatabaseSelections
contains a lot of properties and/or larger values, you risk exceeding the query string limit and throwing an exception. A better approach is just to pass the ID
property of the AssignedDatabaseSelection
and get the object again in the GET method if you need other properties of it.
@Html.ActionLink(Strings.CsvLabel, "DownloadSelection", "Home",
new { ID = selection.ID, Format = DownloadFormat.CSV }, null)
Upvotes: 1
Reputation: 26989
Here is an example of how to create a link with properties from an object. I am including the code of creating a new Employee within the view but this can/should be in the model:
@{ var emp = new Employee { Name = "Tom", Age = 44 }; }
@Html.ActionLink("Test", "Test2", "Account", new {Name = emp.Name, Age = emp.Age }, null)
Please note how I am passing each property of the Employee
into the anonymous object for the route values.
The above link will work with this action. The DefaultModeBinder will take the names from the query string in the link and assign it to the properties of the Employee
and pass it to the action below:
public ActionResult Test2(Employee emp)
{
return null;
}
Upvotes: 1