0

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&amp;Format=CSV">Excel</a>

Now, the format is filled, but the selection is always null. What am I missing?

7
  • Does your selection work if you do not add the format parameter? Commented Jun 4, 2017 at 22:18
  • mh, not when I pass it in a new object like new {selection = selection} Commented Jun 4, 2017 at 22:21
  • So it has nothing to do with the 2nd parameter. And how are you assigning a selection? Commented Jun 4, 2017 at 22:22
  • you mean in the view? I read it out of the view model. so, that would mean I have to make a new view model an passt this one ot the controller? Commented Jun 4, 2017 at 22:27
  • but the interessting thing is, that the second parameter is correctly passed, just not the first one. Commented Jun 4, 2017 at 22:30

2 Answers 2

1

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)
Sign up to request clarification or add additional context in comments.

Comments

1

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.