Getting the ID from the Route data in ASP.NET 5 API - asp.net-web-api2

I'm implementing an ASP.NET 5 API where I have the following POST method:
[HttpPost("{id}")]
public void Post([FromBody]string value)
{
// Do something
)
For me to process the request, I need both the ID and the string value which will be in the body.
I realize that I can also put the ID in the body but I was wondering if there's a way for me to get the ID directly from the route data -- like in MVC 4/5 where I'd use the following syntax:
var id = (string)this.RouteData.Values["id"];
What's the best way for me to get the ID value in ASP.NET 5? Use the code above or some other way?

You can decorate your parameter with [FromRoute]:
[HttpPost("{id}")]
public void Post([FromRoute] string id, [FromBody] string value) {
// Do something
)

Related

In ASP.NET Core, is it possible to generate a URI in the controller for a Get action that takes two parameters? If so how?

I have an association controller called ConnectionManagerCategoriesController. It has two Get methods on it. One to get all Categories for a ConnectionManager and one to only retrieve one Categoy for the ConnectionManager based upon the name. I have a Post to create a new category and I am trying to generate a uri for LinkGenerator. However when the URI that is created, it uses the GetConnectionManagerCategories method instead of the GetConnectionManagerCategory. I dont know why or how to do it differently.:
[Route("api/connectionmanagers/{connectionManagerID:int}/categories")]
[ApiController]
public class ConnectionManagerCategoriesController : ControllerBase
{
private readonly LinkGenerator _linkGenerator;
[HttpGet]
public async Task<ActionResult<IEnumerable<ConnectionManagerModel>>> GetConnectionManagerCategoriesAsync(int connectionManagerID){}
[HttpGet("{categoryName}", Name = "GetConnectionManagerCategoryAsync")]
public async Task<ActionResult<ConnectionCategoryModel>> GetConnectionManagerCategoryAsync(int connectionManagerID, string categoryName){}
[HttpPost]
public async Task<ActionResult<ConnectionCategoryModel>> AddConnectionCategoryAsync(int connectionManagerID, string categoryName, [FromHeader(Name = "x-requestid")] string requestId)
{
var url = _linkGenerator.GetUriByRouteValues(HttpContext,
"GetConnectionManagerCategoryAsync",
values: new { connectionManagerID, categoryName = commandResult.CategoryName });
return Created(url, commandResult);
}
It returns the following uri to Swagger: 'http://localhost:6704/api/connectionmanagers/1/categories?categoryName=Almost'
However, when I log the uri in the code it is: http://localhost:6704/api/connectionmanagers/1/categories/newvalueadded
Is this even possible?
You have to show how are trying to run the action, in order to get some explanations. Routing is very tricky and it is better not to try to create routes the way you are creating.
IMHO , it is always a good idea to define the whole route, not just the part. Especially if you use Swager
[HttpGet("{~/api/connectionmanagers/{connectionManagerID:int}/categories/{categoryName}")]
public async Task<ActionResult<ConnectionCategoryModel>> GetConnectionManagerCategoryAsync(int connectionManagerID, string categoryName){}

ASP.NET Core 3.1 unable to get Odata Query parameter

Using ASP.NET Core 3.1 and Microsoft.AspNetCore.OData 7.5.6,
When a HTTP "DELETE" request is sent to an action method, I am unable to get the
query parameter, the resulting parameter value remains set to 0.
Here is my HTTP Request:
https://localhost:8083/api/EventTypes(Id%3D66L)
And my Action Method:
[Route("api/EventTypes({Id})")]
[HttpDelete]
// [AcceptVerbs("DELETE")]
public async Task<IActionResult> Delete(Int64 Id)
{
DynamicParameters param = new DynamicParameters();
param.Add("Id", Id);
await Dapper.DapperORM.ExecuteWithoutReturn("event_type_delete", param);
return Ok();
}
When I inspect the value of Id the value is 0. I have tried changing the type to string, and then the value is set to "Id=66L".
I expect this to work but it does not in my case:
Delete([FromODataUri]Int64 Id)
What is the best/correct way to get the integer value?
Changing the Route Parameter to use this format Id={Id} and using FromODataUri I managed to get the desired parameter value.
e.g.
[Route("api/EventTypes(Id={Id})")]
[AcceptVerbs("DELETE")]
public async Task<IActionResult> Delete([FromODataUri]Int64 Id)

what is the usage of name Property in HttpGet ( such as [HttpGet("/products2/{id}", Name = "Products_List")])

In asp.net core, I seen
[HttpGet("/products2/{id}", ***Name = "Products_List")]***
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
what is the usage of name Property in HttpGet (such as[HttpGet("/products2/{id}", Name = "Products_List")])
And, How Can I read/send a Multipart/form-data from/to an apiapicontroller/client?
Yes, it can be used like this. The second parameter of Url.Link is an object.
#Url.Link("Products_List", new { id = 1 })
Also this property RouteUrl can use it.
#Url.RouteUrl("Products_List",new { id=2})
About route name, this is the official introduction:
The route names give the route a logical name. The named route can be used for URL generation. Using a named route simplifies URL creation when the ordering of routes could make URL generation complicated. Route names must be unique application wide.
Route names:
Have no impact on URL matching or handling of requests.
Are used only for URL generation.
If you send a Multipart/form-data. The apicontroller can get it with FromForm.
[HttpGet("routepath")]
public IActionResult get([FromForm]SampleModel model)
{
//...
}
I found that can be used to string uri = Url.Link(“ Products_List”, id = 1);
Is there Some one can give me more detailed information?

Route to allow a parameter from both query string and default {id} template

I have an action in my ASP.Net Core WebAPI Controller which takes one parameter. I'm trying to configure it to be able to call it in following forms:
api/{controller}/{action}/{id}
api/{controller}/{action}?id={id}
I can't seem to get the routing right, as I can only make one form to be recognized. The (simplified) action signature looks like this: public ActionResult<string> Get(Guid id). These are the routes I've tried:
[HttpGet("Get")] -- mapped to api/MyController/Get?id=...
[HttpGet("Get/{id}")] -- mapped to api/MyController/Get/...
both of them -- mapped to api/MyController/Get/...
How can I configure my action to be called using both URL forms?
if you want to use route templates
you can provide one in Startup.cs Configure Method Like This:
app.UseMvc(o =>
{
o.MapRoute("main", "{controller}/{action}/{id?}");
});
now you can use both of request addresses.
If you want to use the attribute routing you can use the same way:
[HttpGet("Get/{id?}")]
public async ValueTask<IActionResult> Get(
Guid id)
{
return Ok(id);
}
Make the parameter optional
[Route("api/MyController")]
public class MyController: Controller {
//GET api/MyController/Get
//GET api/MyController/Get/{285A477F-22A7-4691-AA51-08247FB93F7E}
//GET api/MyController/Get?id={285A477F-22A7-4691-AA51-08247FB93F7E}
[HttpGet("Get/{id:guid?}"
public ActionResult<string> Get(Guid? id) {
if(id == null)
return BadRequest();
//...
}
}
This however means that you would need to do some validation of the parameter in the action to account for the fact that it can be passed in as null because of the action being able to accept api/MyController/Get on its own.
Reference Routing to controller actions in ASP.NET Core

Web API 2 giving me a 404 on a long id paramter

I'm using Web API 2 (with MVC 5) to access some data from a MongoDb store. This is the action/method:
[Route("api/container/children/{parentId}")]
[HttpGet]
public HttpResponseMessage GetChildren(String parentId) {
ObjectId containerId;
if (!ObjectId.TryParse(parentId, out containerId)) {
IEnumerable<Container> containers = this.Connection.GetCollection<Container>().FindAs<Container>(Query.EQ(Container.FieldNames.ParentId, containerId));
return this.Request.CreateResponse<Container[]>(HttpStatusCode.OK, containers.ToArray());
}
return this.Request.CreateResponse(HttpStatusCode.NotFound);
}
Calling the method from jQuery with a $.get keep getting me a 404 when calling with the parameter ObjectId.Empty (which is 000000000000000000000000), so calling this Url gives me a 404:
/api/container/children/000000000000000000000000
but calling this url works fine:
/api/container/children/0000000000000000
is there some sort of limit to the length of the (id) parameter on Web API 2?
This is not a WebAPI problem.
The bug in the code is actually very simple. Remove the not (!) operator in the if condition
[Route("api/container/children/{parentId}")]
[HttpGet]
public HttpResponseMessage GetChildren(String parentId) {
ObjectId containerId;
if (ObjectId.TryParse(parentId, out containerId)) {
...
}
return this.Request.CreateResponse(HttpStatusCode.NotFound);
}