Question3r
Question3r

Reputation: 3802

generate resource URL within controller endpoint

I want to minimize my API response bodies by replacing information about subresource with a resource URL. So let's say you would fetch a vendor and don't want to list all the products he is selling but you want to provide a URL that leads to those information.

For example I tried this in my controller endpoint

string resourceUrl = Url.Link(nameof(GetVendorById), new { id = 1 });

and was expecting to get the following string

https://localhost:5001/vendors/1

Unfortunately the string returns null. So how do you generate such resource urls?

The following dummy code is just an example of what I want to achieve, I know I shouldn't return the vendor products when fetching a vendor.

[HttpGet("{id:int}")]
public async Task<ActionResult<VendorResponseModel>> GetVendorById([FromRoute] int id)
{
    VendorResponseModel vendor = new VendorResponseModel()
    {
        Id = id,
        Name = "Vendor " + id,
        Products = new List<VendorProductResponseModel>()
        {
            new VendorProductResponseModel()
            {
                Id = 1,
                ResourceUrl = Url.Link(nameof(ProductsController.GetProductById), new { id = 1 })
            }
        }
    };

    return Ok(vendor);
}

Upvotes: 1

Views: 1071

Answers (2)

Question3r
Question3r

Reputation: 3802

Url.Link does work for me when tagging the resource method with a Name attribute. So when calling Url.Link(nameof(GetVendorById), new { id = 1 }); I had to make sure that the GetVendorById method is named like so

[HttpGet("{id:int}", Name = "GetVendorById")]
public async Task<ActionResult<VendorResponseModel>> GetVendorById([FromRoute] int id)
{
    // ...
}

Upvotes: 1

Formula12
Formula12

Reputation: 397

//Generates a relative URL to your current request
//E.g you are on a page in a folder named vendors that contains index.cshtml, 
//create.cshtml, details.cshtml And the current request is on create.cshtml,
// the preceding code will generate a URL relative to your current url 
//{"baseurl/vendors/details/556"}
var resourceUrl = Url.Page("/details", pageHandler:null, 
        values: new { productId = 123, otherId = 556 }, protocol: Request.Scheme);

//Used normally for MVC controllers
Url.Action("yourAction", "yourController", new { myId =455}, Request.Scheme);

//Gets the URL of the current request
Url.ActionContext()

//Generates a URL with your base URL appended to it
Url.Content("~/tyuu/you/557")

//Generates an absolute URL 
Url.Link("routeName", new { myId = 456 }

//Then you can encode it this way
var encoded = HtmlEncoder.Default.Encode(resourceUrl)

Will give you the URL with all the parameters you want insides of it.
Edit
If you think the problem is the package itself, clean solution, remove all packages and dotnet restore

Upvotes: 1

Related Questions