As far as I can understand, the conventional routing in .NET Core MVC is [controller]/[action]/{id?}
However, I have the following POST request I'm trying to catch which looks like this:
myDomain/MyController/MyAction/userID/anotherID/myInfo
I have tried the following, but it doesn't seem to be working:
public class MyController : Controller
{
[HTTPPost]
[Route("MyAction/{userID:minlength(2)}/{anotherID:int}/myInfo")]
public IActionResult MyAction([FromRoute] string userID, [FromRoute] int anotherID, [FromBody] string stuffIWant)
{
return Ok();
}
}
Obviously I'm not handling the routing correctly, but I'm not sure how I would get userID and anotherID from that route. I've published this action to my site, and tried to do a test post with the same URL, but didn't get a response.
Change to:
public class MyController : Controller
{
[HTTPPost]
[Route("MyAction/{userID:minlength(2)}/{anotherID:int}/myInfo")]
public IActionResult MyAction(string userID, int anotherID, [FromBody] string stuffIWant)
{
return Ok();
}
}
Related
I have two methods:
[HttpGet("{id}")]
public IActionResult GetTask([FromRoute] int id)
{
}
[HttpGet("{userId}")]
public IActionResult GetUserTask([FromRoute] string userId)
{
}
As you can see, i want to pass to my API routes like:
https://localhost:44365/Task/1
and
https://localhost:44365/Task/string
But my WebApi project cant handle it. When i pass route like this:
https://localhost:44365/Task/7dd2514618c4-4575b3b6f2e9731edd61
i get an 400 http and this response:
{
"id": [
"The value '7dd2514618c4-4575b3b6f2e9731edd61' is not valid."
]
}
While debugging, im not hitting any methods (when i pass string instead of int)
My question is, how to verload methods with one parameters with string or int? These methods do diffrent things
EDIT
When i pass something like:
https://localhost:44365/Task/dddd
I still get response with invalid id
You can define parameter type like [HttpGet("{id:int}")]. For more information refer below link.
https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-constraints
Your actions should be like below.
[HttpGet("{id:int}")]
public IActionResult GetTask([FromRoute] int id)
{
}
[HttpGet("{userId}")]
public IActionResult GetUserTask([FromRoute] string userId)
{
}
Use like this
[HttpGet("{id}")]
public IActionResult GetTask([FromRoute] int id)
{
}
[HttpGet("User/{userId}")]
public IActionResult GetUserTask([FromRoute] string userId)
{
}
and while calling api with guid/string use
https://localhost:44365/Task/User/7dd2514618c4-4575b3b6f2e9731edd61
I tried to call the update web api on Postman but it seems that it doesn't pass the id param to the asp.net core controller (asp.net core 2.0)
public class ShoppingCartController : BaseController
{
[HttpPut("{id}")]
[Route("api/ShoppingCart/UpdateShoppingCartItem")]
public IActionResult UpdateShoppingCartItem(long id)
{
return new NoContentResult();
}
}
You have to use [FromBody].
[HttpPut("{id}")]
[Route("api/ShoppingCart/UpdateShoppingCartItem")]
public IActionResult UpdateShoppingCartItem([FromBody]long id)
{
return new NoContentResult();
}
In Postman you must use a simple number.
Replace:
{
"id":87908908
}
with
87908908
Default behaviour of param parsing: From Url.
Use [FromBody] before your method param to let asp parse this param from the Body.
Can you try changing method UpdateShoppingCartItem to the following:
public IActionResult UpdateShoppingCartItem([FromBody] long id)
HttpPut now accepts the route as parameter, so you can combine your attributes.
public class ShoppingCartController : BaseController
{
[HttpPut("api/ShoppingCart/UpdateShoppingCartItem")]
public IActionResult UpdateShoppingCartItem(long id)
{
return new NoContentResult();
}
}
The model binder should infer the value of id from the body.
Using [HttpPut("{id}")] would mean that a put request to localhost:44342/65465 would be a valid action.
I have two projects, one is SPA and the other one is ASP.NET aspx project.
Normally those two projects communicate with each other via web API.
There is a running method like this (from SPA to ASP.NET)
[HttpPost]
[Route("DenyInvoice/{approvalId:long}")]
public IHttpActionResult DenyInvoice(long approvalId)
{
string exMsg = "";
if (DenyInvoice(approvalId, this.UserId, this.Email, out exMsg))
return Ok();
return BadRequest(exMsg);
}
This method works as I wanted, but I want to write a method that accepts a DTO variable like;
[HttpPost]
[Route("InvoiceDetailUpdate/{invoices : invoiceDetailDtoModel}")]
public IHttpActionResult InvoiceDetailUpdate(invoices : invoiceDetailDtoModel)
{
....
}
Is it possible? How should I do this?
Can you help?
Thank you..
Use [FromBody] to pass in the POST parameter. See https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api#implement-the-other-crud-operations for more details.
[HttpPost]
[Route("InvoiceDetailUpdate")]
public IHttpActionResult InvoiceDetailUpdate([FromBody]InvoiceDetailDtoModel invoices)
{
....
}
You want to retrieve parameter via post so there is no required for get parameter routing.
[HttpPost]
[Route("InvoiceDetailUpdate")]
public IHttpActionResult InvoiceDetailUpdate(InvoiceDetailDtoModel invoices)
{
....
}
Also, be careful with the name convention of a class.
In the following code, you can use like this :
public class BooksController : ApiController
{
[Route("api/books")]
public IEnumerable<Book> GetBooks() { ... }
[Route("api/books/{id:int}")]
public Book GetBook(int id) { ... }
[Route("api/books")]
[HttpPost]
public HttpResponseMessage CreateBook(Book book) { ... }
}
Now , you can see this link attribute-routing-in-web-api-2
and change your code to above figure
[Route("api/YourController/InvoiceDetails")]
public IHttpActionResult InvoiceDetailUpdate(InvoiceDetails invoiceDetailsDto)
I am doing a Web API 2 application and I have controller named NCT_ProcessSettings and already I have two GET methods as below.
1. public IEnumerable<Process_Settings> Get()
2. public HttpResponseMessage Get(int id)
Now I want to have third one as below (Same as first one but inside I will write different logic).
3. public IEnumerable<Process_Settings> Get() //Compiler will confuse which to pick?
I tried as below.
[HttpGet]
[Route("GetGlobalSettings")]
public IEnumerable<NCT_Process_Settings> GetGlobalSettings()
{
return entityObject.NCT_Process_Settings.Where(c => c.project_id == 0).ToList();
}
Below is my angularcode to call api.
var url = '/api/NCT_ProcessSettings/GetGlobalSettings';
May I have some idea how to fix this? Any help would be appreciated?
Enable attribute routing in WebApiConfig.cs before convention-based routes.
config.MapHttpAttributeRoutes();
Next update controller to use routing attributes. (note the route prefix)
[RoutePrefix("api/NCT_ProcessSettings")]
public class NCT_ProcessSettingsController : ApiController {
//GET api/NCT_ProcessSettings
[HttpGet]
[Route("")]
public IEnumerable<Process_Settings> Get() { ... }
//GET api/NCT_ProcessSettings/5
[HttpGet]
[Route("{id:int}")]
public HttpResponseMessage Get(int id) { ... }
//GET api/NCT_ProcessSettings/GetGlobalSettings
[HttpGet]
[Route("GetGlobalSettings")]
public IEnumerable<NCT_Process_Settings> GetGlobalSettings() { ... }
}
Read up more documentation here Attribute Routing in ASP.NET Web API 2
Used Action Name attribute
[ActionName("Get")]
public IEnumerable<Process_Settings> Get1()//used any name here
{
}
I'm trying to get the parameters of specific attribute routed URL on ActionFilterAttribute. For instance I have an action like below:
[Route("/v1/test/{userId}/{udid}")]
public object GetNewObject(int userId, string udid)
And in action filter attribute the absolute url is coming something like "http://test.example.com/v1/test/1/123-asda-231-asd". However I want to parse these parameters as userId=1 and udid=... within a collection.
Is it possible?
Anyway I found the answer,
Within RouteData of ControllerContext we may able to retrieve the specified value.
actionContext.ControllerContext.RouteData.Values["udid"]
[Route("...")] is possible only in MVC 5.
I think you want to do something like this
[RoutePrefix("api/users")]
public class UsersController : ApiController
{
// GET api/users
[Route("")]
public IEnumerable<User> Get() { ... }
// GET api/user/5
[Route("{id:int}")]
public Book Get(int id) { ... }
// POST api/users
[Route("")]
public HttpResponseMessage Post(User book) { ... }
}
where each User contains your properties
public class User
{
int UserId{get;set;}
string Udid{get; set;}
}