asp.net WebAPI list in Get request - asp.net

I understand in Web API Get request, we can pass the list of inputs in query string like
Products?id=1&id=2&id=3
so the Get action method in ProductsController will be
Get([FromURI] int[] id)
{
}
My question now is, if the list of inputs to the Get call is much more (assume 1000), what is the recommended approach?
Comma separated values in query string will be some help. But that won't help in my case.Is there any other way to pass these inputs other than in query string?

Related

Optional Query Params and composed data

I'm trying to figure it out how to build a query string with some important information to be fetched. For example, I have this struct I'm going to decode the query into:
SomeObject{
Names []string
Attr Attribute
}
Atribute{
Group string
City string
}
So, initially I understand passing the names in the query string should look like this:
HTTP://localhost:8000/api/retrieve?names=oneName&names=anotherName
And I can get the names[oneName anotherName] correctly. But now I must build the query to get the attributes in order to get: attributes{group{someGroup} city{Delhi}}. How should the query string be written????
Question it's not related to the HTTP request handlers, but how the params should look to get correctly
Thanks in advance

Delete WebApi FromURI binding

I am trying to create a .NET5 WebApi delete method in a controller class where this method receives several "ids" that will be used for deleting some entities.
I realized when building the delete request on the client side that specifying a content does not make sense. So I was guided to pass ids on the Uri, hence the use of the "FromUri" attribute:
// DELETE: api/ProductionOrders/5
[HttpDelete("ProductionOrders")]
public IActionResult DeleteProductionOrder([System.Web.Http.FromUri]int[] ids)
{
//code
}
If this is a reasonable approach, is there a better way to build this Uri from the client-side? Imagine instead of an array of ints I had a complex type. How can I serialized this and put into the Uri?
For this example I end up building up a URI like this:
http://localhost:51081/api/ProductionOrders?ids=25563&ids=25533
Personally, if I have to pass a List or a complex type I would map values from the Body via JSON. The DELETE allow using body. And then just decorate your param with [FromBody] attribute.
Despite some recommendations not to use the message body for DELETE requests, this approach may be appropriate in certain use cases.
This allows better extensibility in case you need to change how the data is coming.
In your case with ids I’d create new class like this:
public class RequestEntity {
[JsonPropertyName("Ids")]
public List<int> Ids { get; set; }
}
And then when calling this method, send the Body along with the request.
{
"Ids": [25392, 254839, 25563]
}
In a future you can pass complex objects just by changing what is send to server and implement complex logic.

How can I add multiple Get actions with different input params when working RESTFUL?

I'm trying to figure out whats the best way to have multiple Get actions in a REST controller.
I would like to do something like this:
Get By Id:
public ResponseType Get(Guid id)
{
// implementation
}
Get By Enum Type:
public ResponseType Get(EnumType type)
{
// implementation
}
Get By Other Enum Type:
public ResponseType Get(OtherEnumType otherType)
{
// implementation
}
etc..
Now when I do something like that, I get the next error message:
Multiple actions were found that match the request
I understand why I get the message and I was thinking how is the best way to do something like that (I want to stick with REST).
I know I can add a route like this:
routeTemplate: "api/{controller}/{action}/{id}"
But then I would need to change the action names and the urls - And this seems like a workaround when we are talking about rest.
Another thing I thought was to create multiple controllers with one Get - But that seems even wronger.
The third workaround was to handle one Get action with an input param that will have the state:
public ResponseType Get(ReqeustObj obj)
{
switch(obj.RequestType)
{
case RequestType.GetById:
// etc...
}
}
Anyway, I would like to know whats the best way to do something like that in REST (WebApi).
As you now, when Web API needs to choose an action, if you don't specify the action name in the route, it looks for actions whose name starts with the method name, GET in this case. So in your case, it will find multiple methods.
But it also try to match the parameters. So, if you include the parameters as part of the url (route parameters) or the query string, the action selector will be able to choose one of the available methods.
If you don't specify a parameter or specify the id in the url (or even in the query string) it should invoke the first overload. If you add the parameter name of the second action in the query string like this: ?type=VALUE it should choose the corresponding overload, and so on.
The question is that the parameter names must be different, or it will not be able to choose one or the other among all the overloads.
For example, if you use the urls in the comments in your browser, you'll see how the right method is chosen:
public class TestController : ApiController
{
// GET api/Test
public string Get()
{
return "without params";
}
// GET api/Test/5
public string Get(int id)
{
return "id";
}
// GET api/Test?key=5
public string Get(string key)
{
return "Key";
}
// GET api/Test?id2=5
public string Get2(int id2)
{
return "id2";
}
}
NOTE: you can also use route constraints to invoke differet methods without using query string parameters, but defining different route parameter names with different constraints. For example you could add a constraint for id accepting only numbers "\d+" and then a second route which accepts "key" for all other cases. In this way you can avoid using the query string

how to pass multiple key/value pairs in a single variable using query string?

I have one requirement like passing multiple values in the query string in a single variable.
Id=(refine_1=cgid=womens&refine_2=c_refinementColor=Black&refine_3=price=(0..500))
Is it possible to accept value like above sample from the query string?if yes,please tel me how to achieve this?
You should URL encode it:
?id=(refine_1%3Dcgid%3Dwomens%26refine_2%3Dc_refinementColor%3DBlack%26refine_3%3Dprice%3D(0..500))
Now assuming that your controller action takes an id parameter:
public ActionResult SomeAction(string id)
{
...
}
the value of this parameter inside the action will be (refine_1=cgid=womens&refine_2=c_refinementColor=Black&refine_3=price=(0..500)).
You could bring this even a step further and write a custom model binder that will parse this value and bind it to a view model containing those properties that your controller action could take as parameter instead of a id string parameter.

multiple dispatcher is requiered

did we need multiple request-dispatcher to send multiple value to the same page
I have written this.
String name=rs.getString("itemname");
String code=rs.getString("itemcode");
String lpr=rs.getString("lastpurchase");
String ur=rs.getString("unitrate");
String pq=rs.getString("pquantity");
String cpq=rs.getString("costpquan");
ServletContext context= getServletContext();
RequestDispatcher rd=context.getRequestDispatcher("/index.jsp")
rd.forward(request,response);
I need to send all these variables to a same page.
No, you don't need multiple dispatchers. You simply need to store each value in a separate request attribute. A better option would be to create an object (Item, for example) containing all these values, and to store this object in a single request attribute.
Item item = new Item(name, code, lpr, ur, pq, cpq);
request.setAttribute("item", item);
rd.forward(request,response);
You should also use much better names for your variables.

Resources