ploeh / Hyprlinkr

A URI building helper library for ASP.NET Web API
MIT License
197 stars 34 forks source link

A link to another controller's parameterless method includes current request's parameter #46

Open roman-po opened 7 years ago

roman-po commented 7 years ago

I've started using Hyperlinkr just a week or so ago, not long after I started working with Web Api 2. I came across what looks like an issue to me, but it could also be that my expectation is wrong.

So, my problem is that while processing a request with a single Id parameter I try to get a link to a parameterless resource served by another controller and the resulting link includes the Id of the current request. I see that the very same behaviour is exhibited by the HomeController in ExampleService. E.g. the response for http://localhost:6788/custom/route/5 is

{
"links": 
[{
    "href": "http://localhost:6788/custom/route/5",
    "rel": "self"
}, {
    "href": "http://localhost:6788/home/5",
    "rel": "http://sample.ploeh.dk/rels/home"
}],
"name": "5"
}

The second "href" value "http://localhost:6788/home/5" corresponds to the expression Href = this.linker.GetUri<HomeController>(r => r.Get()).ToString(). I cannot see why it should end with /5.

Am I missing something?

Thanks, Roman.

ploeh commented 7 years ago

Thank you for writing. That does, indeed, look like a bug. In fact, it looks like a bug in ASP.NET Web API, because if you change the ExampleService HomeController.Get(string) to create the second link like the following, you still see the same behaviour:

new AtomLinkModel
{
    Href = this.Url.Link("DefaultApi", new { Controller = "home" }),
    Rel = "http://sample.ploeh.dk/rels/home"
}

I haven't checked whether it's an issue with the new ASP.NET Core framework, but it seems to be an issue at least with the version of ASP.NET Web API used by ExampleService.

roman-po commented 7 years ago

Thanks for confirming my suspicions. The behaviour of Web Api is indeed flawed and by briefly looking at its code I cannot see any obvious bug.

The only way I found to get a proper link is to use named route:

[Route("home", Name = "HomeDefault")] 
public HomeModelCollection Get()
{...}

Then Href = this.Url.Link("HomeDefault", null) results in "href":"http://localhost:6788/home".