Sunday, June 11, 2017

UrlHelper.Link returns undesired parameters

Leave a Comment

If I call UrlHelper.Link within an API call which has a parameter matching an optional parameter of the API endpoint I'm attempting to obtain an URL for, UrlHelper.Link returns a URL with values from the current request no matter how I try to exclude the optional parameter from the link.

e.g.

[HttpGet] [Route("api/Test/Stuff/{id}")] public async Task<IHttpActionResult> GetStuff(int id) // id = 78 {     string link = Url.Link("Mary", new     {         first = "Hello",         second = "World"     });      string link2 = Url.Link("Mary", new     {         first = "Hello",         second = "World",         id = (int?)null     });      string link3 = Url.Link("Mary", new     {         first = "Hello",         second = "World",         id = ""     });      return Ok(new     {         link,         link2,         link3     }); }  [HttpGet] [Route("api/Test/Another/{first}", Name = "Mary")] public async Task<IHttpActionResult> AnotherMethod( [FromUri]string first, [FromUri]string second = null, [FromUri]int? id = null) {     // Stuff     return Ok(); } 

GET http://localhost:53172/api/Test/Stuff/8

returns

{   "link": "http://localhost:53172/api/Test/Another/Hello?second=World",   "link2": "http://localhost:53172/api/Test/Another/Hello?second=World&id=8",   "link3": "http://localhost:53172/api/Test/Another/Hello?second=World&id=8" } 

How do you get Url.Link to actually use the values you pass it rather than pull it from the current api request when they are not presented or assigned to null or empty string?

I believe the issue is very similar to ....

UrlHelper.Action includes undesired additional parameters

But this is Web API not MVC, not an action and the answers provided do not seem to yield an obvious solution to this issue.

EDIT: I've updated the code as the original code didn't actually replicate the issue. I've also included a request URL and the response returned, which I've tested. Whilst this code demonstrates the issue, the code I'm trying to find a fix for is not passing an anonymous type to UrlHelper, instead its a class which generates a timestamp and hash and has 4 optional parameters. If there's another solution which doesn't require omitting the optional parameters in the structure passed to UrlHelper I'd like to have it, as it'll save me from making a lot of changes to the code.

1 Answers

Answers 1

Do not include the id when passing the route values. In fact it should not allow you to compile as

Cannot assign <null> to anonymous type property

public async Task<IHttpActionResult> GetStuff(int id) // id = 78 {     string myUrl = Url.Link(         "Mary",          new          {              first = "Hello World"         });      //...other code } 

Tested with web api 2 and id was not included when linking to other action.

[RoutePrefix("api/urlhelper")] public class UrlHeplerController : ApiController {      [HttpGet]     [Route("")]     public IHttpActionResult GetStuff(int id) {         string myUrl = Url.Link(             "Mary",             new {                 first = "Hello World",            });         return Ok(myUrl);     }      [HttpGet]     [Route(Name = "Mary")]     public IHttpActionResult AnotherMethod(     [FromUri]string first,     [FromUri]string second = null,     [FromUri]int? id = null) {         // Stuff         return Ok();     } } 

Calling

client.GetAsync("/api/urlhelper?id=78") 

routed to the GetStuff action and the link generated

"http://localhost/api/urlhelper?first=Hello%20World" 

Even when tested with

string myUrl = Url.Link(     "Mary",     new {         first = "Hello World",         id = ""     }); 

id was not included in the generated link.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment