user270124
user270124

Reputation: 537

Asp-route-id: passed integer becomes 0

I have the following problem. I have a product for which I run some tests. In my cshtml page, I show the test runs for some product item, like this:

<td><a asp-action="TestDetail" asp-route-id="@Model.ResultViewModels[i].TestRunId">Content</a></td>

TestRunId is an integer. For example, TestRunId could be 9. This works: the URL looks correct. In my cshtml page, the user can click on this, to see more details.

However, when I log the asp-route-id in my controller, this TestRunId seems to be 'lost'. In my example below, the second logging shows testrunId: 0. I expect this to be also 9.

        public IActionResult TestPlanRunDetail(int TestRunId)
        {
            logger.LogInformation("TestPlanRunDetail function called.");
            logger.LogInformation("TestRunId: " + TestRunId);
            // Omitted for brevity
            return View(detail);
        }

Upvotes: 0

Views: 1119

Answers (2)

ytan11
ytan11

Reputation: 931

asp-route-{value} is an Anchor Tag Helper.

The Anchor Tag Helper enhances the standard HTML anchor (<a ... ></a>) tag by adding new attributes. By convention, the attribute names are prefixed with asp-. The rendered anchor element's href attribute value is determined by the values of the asp- attributes.

The Reason:

Any value occupying the {value} placeholder is interpreted as a potential route parameter

Therefore, if you use asp-controller="controller" asp-action="action" asp-route-id="@Model.ResultViewModels[i].TestRunId".

The generated HTML href will be href="/controller/action?id=0">Content</a> where 0 is the actual @Model.ResultViewModels[i].TestRunId.

Notice that the parameter name in href is id instead of TestRunId?

Your TestPlanRunDetail(int TestRunId) take TestRunId, but not id, and that is why you get TestRunId=0.

The Easier Solution:

Change asp-route-id to asp-route-TestRunId (or asp-route-testrunid as it is not case sensitive).

Alternate Solution:

Define a default route template in Startup.Configure:

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{action=Index}/{id?}");
});

In the model:

<a asp-action="TestDetail" 
   asp-route-id="@Model.ResultViewModels[i].TestRunId">
       Content
</a>

Then, the generated href will be href="/TestDetail/12".

Upvotes: 0

LazZiya
LazZiya

Reputation: 5719

The parameter name in asp-route-xxx must be same as the parameter name in the backend (int xxx)

So, change one of your param names to match the other

Upvotes: 3

Related Questions