I have a Blazor WebAssembly Hosted project and am in need of posting up an Array of Ids to get.
[AllowAnonymous]
[HttpGet("GetByTypePaged/{ingredientTypeIds}/{startIndex}/{count}/{search?}")]
public async Task<IActionResult> GetByTypePaged([FromQuery]int[] ingredientTypeIds, int startIndex, int count, string? search)
However the ingredientTypeIds comes back as int[0] so no Ids are being retrieved. Ive tried FromRoute and i get a 415 as well as without FromQuery
FromUri does not exist within the name spaces
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
Id have to install the Microsoft.AspNet.WebApi.Core nuget package to get the System.Web.Http namespace. However, then the
[Authorize]
[Route]
[HttpGet]
etc all have ambiguity between the System.Web.Http and AspNetCore. If I remove the references to the Microsoft.AspNetCore then I loose the [FromBody] for my HttpPut operation.
public async Task<IActionResult> Update(int id, [FromBody] Ingredient ingredient)
Whats my best approach here
[HttpGet("GetByTypePaged/{ingredientTypeIds}/{startIndex}/{count}/{search?}")]
In your code we can find you defined a route with route parameters ingredientTypeIds, startIndex, count and optional one search.
Please note that route data and query string values are used only for simple types, if you'd like to pass an array of Ids in URL and bind to action parameter int[] ingredientTypeIds, you can modify your route and pass it through query string in this format:
ingredientTypeIds[0]=1&ingredientTypeIds[1]=2
Besides, if you'd like to pass complex-type data to your backend API, you can make your endpoint support the HTTP POST method, and you can pass the expected data through request body.
Related
I'm using dot.net WebApi2 and I'm getting Veracode Flaw from code scan:
'The Controller's Action is missing a Route Attribute that will perform input validation on Action parameters using a Route Constraint....
Remediation: Make sure to use RouteAttribute objects with a Route Constraint on each Action'
The action referred to is:
[Route]
[HttpGet]
public IHttpActionResult Get(int? offset = null, int? rows = null)
{
...
}
Since I only have optional parameters, they are not specified in the Route attribute. If I do by changing thr route annotation to:
[Route("{offset:int?}/{rows:int?}"]
the route would show in the swagger api help page like this:
GET /api/v1/foo/{offset}/{rows}
instead of (what we want to show):
GET /api/v1/foo
the help page would also have those parameters marked as required, even though they should not be.
Is there a way I can please Veracode and not spoil my swagger doc's?
I have two simple routing methods:
main routing directive:
[RoutePrefix("api/accounts")]
first one
[Route("user/{id:guid}", Name = "GetUserById")]
public async Task<IHttpActionResult> GetUser(string Id)
second one
[Route("user/del/{id:guid}")]
public async Task<IHttpActionResult> DeleteUser(string id)
I wonder why if I test the first method with direct ulr ( GET ) it works:
http://localhost/ReportApp_WebApi/api/accounts/user/1533882b-e1fd-4b52-aeed-4799edbbcda6
And if I try the second link that is just a little different:
http://localhost/ReportApp_WebApi/api/accounts/user/del/1533882b-e1fd-4b52-aeed-4799edbbcda6
I get: The requested resource does not support http method 'GET'.
Can you help me?
The second link is not just a little different. In fact it is pointing to the route that you have defined for your delete method. This method expects DELETE Http verb.
When you write the url directly on the browser it performs a GET request. If you want your delete method to work with a GET verb you have to put the attribte
[HttpGet]
before or just after your Route atttribute. Although this I would not recommend to do it. You can have a HTTP client like Fiddler or Postman to test this
Web Api uses conventions when naming methods in your controllers. Because you named your method DeleteUser, Web Api expects Delete verb.
EDIT>>>Please follow recommendations listed in comments. I have also make bold the part where I do not recommend this
I am working on building CRUD OData (ODataController) controllers. For this request
PATCH http://localhost/MySite/api/MyData(1)
a PATCH action declared as below works. The model has single property marked with KeyAttribute
public async Task<IHttpActionResult> Patch(
[FromODataUri] int key,
Delta<MyModel> modelDelta)
This one doesn't work (note that I named parameter id instead of key). It returns 404 - resource not found:
public async Task<IHttpActionResult> Patch(
[FromODataUri] int id, // <--- invalid argument name?
Delta<MyModel> modelDelta)
I also tried to mark this action with [ODataRoute("({id})")] but I get this
The path template '({id})' on the action 'Patch' in controller 'MyData' is not a valid OData path template. Empty segment encountered in request URL. Please make sure that a valid request URL is specified.
Do I have flexibility to name parameters specifically? And especially when I may have 2-3 keys/parameters. I want to be able to use patch as
public async Task<IHttpActionResult> Patch(
[FromODataUri] int id1,
[FromODataUri] int id2,
Delta<MyModel> modelDelta)
Is your class declared like this:
//Must declare this attribute to relative ODataRoute Works
[ODataRoutePrefix("MyData")]
public class MyDataController : ODataController
....
otherwise must declare the route
[ODataRoute("MyData({id})")]
...
I am using WebAPI 2 with EF and scaffolding webapi controllers from visual studio.
Each controller is created with 4 default verbs (GET,PUT,DELETE,POST) and 5 actions. while there are two versions of GET action.
IQueryable<entity> GetEntities ()
Task<IHttpActionResult> GetEntity(GUID key) // default is int id but I changed to guid.
I am using attribute routing and route prefix for the controller. just some fancy keywords for better management of url. [RoutePrefix("api/v3/Company")]
Problem :
Ideally when a wrong parameter is sent in url, it should return error, but it is not raising error, instead it fall back to the action without parameter.while if I send a wrong GUID, it shows error.
Like if I call :
http://localhost:8080/api/v3/Company/1f7dc74f-af14-428d-aa31-147628e965b2
it shows the right result.
when I call :
http://localhost:8080/api/v3/Company/1f7dc74f-af14-428d-aa31-147628e96500 (wrong key)
it set back to GetEntity() function and shows all records
when I call:
http://localhost:8080/api/v3/Company/1 (not a GUID length parameter)
it do the same and shows all records.
I am using attribute [Route("{id:guid}")]
Really appreciate if I can get some guidance on this!
It is most likely that the route is defaulting back to the convention-based mapping.
You need to explicitly make apply the route attribute on actions to let the routing know that it is the default route got GET
[RoutePrefix("api/v3/Company")]
public class CompanyController : ApiController {
//GET api/v3/Company
[HttpGet]
[Route("")] //Default Get
public IQueryable GetEntities() { ... }
//GET api/v3/Company/1f7dc74f-af14-428d-aa31-147628e965b2
[HttpGet]
[Route("{id:guid}")] // ALSO NOTE THAT THE PARAMETER NAMES HAVE TO MATCH
public Task<IHttpActionResult> GetEntity(Guid id) { ... }
//...other code removed for brevity
}
Make sure that attribute routing is enabled in the web api config
config.MapHttpAttributeRoutes();
I have a Web API action that looks like the following:
[HttpGet]
[Route("api/query/hello/{query}")]
public HttpResponseMessage Hello([FromUri]Query query)
{
return null;
}
where the Query class has a public string property named QueryText. When I hit the following URL, I get a 404 error:
/api/query/hello?QueryText=bacon
This worked before I started using Attribute Routing. If I have no parameters or primitive type parameters, I can get Attribute Routing to work. But with a complex parameter, I get 404s. How does Attribute Routing work with complex action parameters? Is it compatible with the FromUri attribute?
The solution here was that the {query} token in the Route definition was superfluous. Removing it, as follows, fixed the issue:
[Route("api/query/hello")]
The [FromUri] attribute will be needed because you're reading from the URL. Your route should look something like:
public HttpResponseMessage Hello([FromUri]Query query)
{
//Implement whatever
return null;
}
/api/{Controller Name}/hello?QueryText=bacon
Should then work correctly.
The model binder will take whatever query parameters you provided then try to bind whatever is inside that Query object. I'd worry about the Route Attribute after you've got it working first.