How to use an ArrayList as Query parameter in retrofit - retrofit

I'm trying to do something like this:
#GET("values")
Call<List<Values>> getResult(#Query("ids") List<String> ids);
My desired request is something like this:
server.com/values?ids=abc%2Cdef%2Cghi%2Cjkl
Actual request is this:
server.com/values?ids=abc&ids=def&ids=ghi&ids=jkl
How can I achieve the desired request?

Finally, figured this out. This was my approach to going this:
First, convert ArrayList into an encoded string:
String uriString = null;
try {
uriString = URLEncoder.encode(TextUtils.join(",", ids), "utf-8");
} catch (UnsupportedEncodingException e) {
// Catch the exception
}
And then do the following while making the retrofit call:
#GET("values")
Call<List<Values>> getResult(#Query(encode=true, value="ids") String ids);
Setting encode = true is extremely important, otherwise your % will be further encoded and you will never be able make the desired call.

Related

Can I disable model binding and use the raw request body in an action in dotnet core?

I want to setup an endpoint for testing webhooks from third parties. Their documentation is uniformly poor and there is no way ahead of time to tell exactly what I will be getting. What I've done is setup an ApiController that will just take a request and add a row to a table with what they are sending. This lets me at least verify they are calling the webhook, and to see the data so I can program to it.
// ANY api/webook/*
[Route("{*path}")]
public ActionResult Any(string path)
{
string method = Request.Method;
string name = "path";
string apiUrl = Request.Path;
string apiQuery = Request.QueryString.ToString();
string apiHeaders = JsonConvert.SerializeObject(Request.Headers);
string apiBody = null;
using (StreamReader reader = new StreamReader(Request.Body))
{
apiBody = reader.ReadToEnd();
}
Add(method, name, apiUrl, apiQuery, apiHeaders, apiBody);
return new JsonResult(new { }, JsonSettings.Default);
}
This works great, except for this new webhook I am usign that posts as form data so some middleware is reading the body and it ends up null in my code. Is there any way to disable the model processing so I can get at the request body?
You could actually use model binding to your advantage and skip all that stream reading, using the FromBody attribute. Try this:
[Route("{*path}")]
[HttpPost]
public ActionResult Any(string path, [FromBody] string apiBody)

Setting a default page size for a WebAPI 2 OData service

I have an ODataController with an endpoint like this:
[EnableQuery]
public IQueryable<Customer> Get()
{
return _context.Customers;
}
And this setting in the Register method of the WebApiConfig:
config.Count().Filter().OrderBy().Expand().Select().MaxTop(100);
There are a lot of Customer entries and I don't want the client requesting too many at once as the query will take a very long time. Luckily this setting means if they do a request like this:
http://domain.com/api/Customers?$top=1000
It'll prevent them from retrieving them as it's higher than 100.
However, if they do a request like this:
http://domain.com/api/Customers
This then attempts to retrieve all customers, which I don't want.
I know I can set the page size like this:
[EnableQuery(PageSize = 10)]
public IQueryable<Customer> Get()
{
return _context.Customers;
}
And this will only return 10 results, however I still want the user to be able to specify their own $top and $skip values for paging (and deciding how many results they want per page). What I want is for there to be a maximum of 100 and a default of 10.
How can I achieve this?
EDIT
I tried the following but it doesn't work properly when using Expand clauses. Any other ideas?
[EnableQuery(MaxTop = 100)]
public IQueryable<Customer> Get(ODataQueryOptions<Customer> queryOptions)
{
IQueryable<Customer> query = _context.Customers;
int? top = queryOptions?.Top?.Value;
if (top == null)
{
query = query.Take(10);
}
return query;
}
Define class:
public class EnableQueryWithDefaultPageSizeAttribute : EnableQueryAttribute
{
const int pageSizeDefault = 10;
public override IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
{
int? top = queryOptions?.Top?.Value;
if (top == null)
{
return queryOptions.ApplyTo(queryable, new ODataQuerySettings { PageSize = this.PageSize == 0 ? pageSizeDefault : this.PageSize });
}
return queryOptions.ApplyTo(queryable); ;
}
}
and use it instance of EnableQuery. See this.
I was facing the same thing, but I was able to get it working. It looks like the order of parameters matters. You'll have to forgive me, I am very new at this and learning as I go, so I hope this actually helps.
My API controller looks like this:
[EnableQuery(PageSize=100)]
public IQueryable<APPLICATION_LOGS> Get()
{
return db.APPLICATION_LOGS;
}
In my client, I am building a request and capturing the response:
string entity = "/AuditApplicationLog";
string expandOptions = "&$expand=APPLICATION, APPLICATIONS_SUBSYSTEMS, FILE";
string parameters = "?$top=100&$count=true";
string url = serviceUri + entity + parameters + expandOptions;
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
This is all a practice project that I am just using to teach myself a few concepts.The page size in my API controller is set to 100 but you'll notice in the parameters variable I am setting a top value. If I set this value to 25, it will return 25. If I set it to 50, it will return 50 etc. Apparently the order I set the parameters matters. If I set the top value before the expand parameters, it works. If I attempt to set it after the expand parameters it returns the default 100, regardless of the value I set top at. It does appear to leave out the "nextPage" link, but that can be accounted for. I hope this helps.

Get Guid with query string

I get a Guid value in a variable like that
var getvalueGuid = db.Clients.Where(u => u.Numero_telephone ==
TextBox_numero_telephone.Text).Select(u => u.GuID).FirstOrDefault();
And i would like to convert it in a query string like that:
getvalueGuid = Request.QueryString["id"];
How to do?
You can use Guid.TryParse:
Guid getvalueGuid;
if(Guid.TryParse(Request.QueryString["id"], out getvalueGuid))
{
// successfully parsed
}
You will be able to get that inside a QueryString, only if you're having the url like
www.example.com/page?id=[guid_here]
Then when you'll use the code, it would provide you with a String which would contain the Query String provided in the URL.
It's hard to understand your question as you're missing a lot of detail, but I think you want to get a strongly-typed GUID value from the querystring?
System.Guid doesn't have a TryParse method, so you'll have to use the constructor and catch any exceptions thrown:
If so, then do this:
String guidStr = Request.QueryString["id"];
Guid guid = null;
try {
guid = new Guid( guidStr );
} catch(ArgumentNullException) {
} catch(FormatException) {
} catch(OverflowException) {
}
if( guid == null {
// Inform user that the GUID specified was not valid.
}
The three exceptions (ArgumentNullException, FormatException, and OverflowException are documented in the notes for the Guid(String) constructor here: http://msdn.microsoft.com/en-us/library/96ff78dc%28v=vs.110%29.aspx
Update:
I forgot that .NET 4.0 introduced the TryParse method. Use that instead if you're using .NET 4.0 or later: http://msdn.microsoft.com/en-us/library/system.guid.tryparse%28v=vs.110%29.aspx
Guid requestGuid;
if (Guid.TryParse(Request.QueryString["id"], out requestGuid))
{
// Do logic here with requestGuid
}

Spring RequestMapping regexp occurrence

I had an url pattern like this:
http://xy.com/param1/value1/param2/value2/..../paramN/valueN
I would like to write a #RequestMapping in Spring colntroller, but I don't know how can I do if I don't know how many param and value will be.
Is there any way to get all params and values to collection?
Or can anybody helpme how to fix this?
Thanks
Why can't you use the standard way without #PathVariables at all? So url will be like
http://xy.com?param1=value1&param2=value2&....&paramN=valueN
and your annotation as:
#RequestMapping("xyz1")
#ResponseBody
public String index(#RequestParam(required = false) String param1, #RequestParam(required = false) String param2,
#RequestParam(required = false) String paramN) {
return "Param1=" + param1 + ", Param2=" + param1 + ", ParamN=" + paramN;
}
#RequestMapping("xyz2")
#ResponseBody
public String index2(HttpServletRequest servletRequest) {
StringBuilder result = new StringBuilder();
for (Entry<String, String[]> entry : servletRequest.getParameterMap().entrySet()) {
result.append(entry.getKey());
result.append('=');
result.append(Arrays.toString(entry.getValue()));
result.append(", ");
}
return result.toString();
}
where #RequestParam is used when all the expected parameters are known and servletRequest.getParameterMap() is used if you really need to handle them dynamically.
Or you can go the hackish way with really optional #PathVariables that is described here.
I was use Spring ModelAttribute instead of

flex3 function not returning String properly

im trying to return a string value from a method inside my script tag however it always returns an object and i cant get at the string value.
Here is the code:
i retrieve the object returned from a webservice call;;
private function getNameResults(e:ResultEvent):String{
var name:Array = new Array(e.result);
var site:String = site_names[0].toString();
Alert.show("site - " +site);
return site;
}
the alert prints out the name fine, however when i try use the value in my next method (which calls the web service which calls getNameResults) i get the object tag
private function getInfo(roomName:String):String{
var site:String =userRequest.getRoomZoneInfo(roomName);
return site;
}
however the value returned here is [object AsyncToken]
any ideas?
You are setting the result of getRoomZoneInfo() to the variable site, but you are casting it as a String. getRoomZoneInfo is returning an object, and because the variable you are sticking it in is a string it is like calling .toString() on the object, which yields the [object AsyncToken].
Basically if getRoomZoneInfo is a webservice call, you cannot get the information you are looking for here, you have to wait until the result comes back and get the string you are looking for there. Make sense?
Your getInfo() method isn't calling getNameResults(). It's calling getRoomZoneInfo(). I don't know what that method does, but I'm guessing it's returning an Object, not a String.
I m getting [ObjectAsyncToken] in variable a instead of string, as I'm retrieving data from database
private function init():void
{
ro.initView();
var a:String=String(ro.getID());
}
database function:
public void initView()
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection("jdbc:odbc:alarmdsn"," "," ");
Statement s = conn.createStatement();
ResultSet r = s.executeQuery("select * from alarm");
while(r.next()) {
a = r.getString(1);
}
}
catch(Exception e) {}
}
public String getID() {
return a;
}

Resources