How to pass custom query parameters in Retrofit? - retrofit

Trying to implement a custom solution for interacting with TestRail API(http://docs.gurock.com/testrail-api2/accessing), I'm kind of stuck in the following situation:
Api calls are made like this: /index.php?/api/v2/get_case/1, meaning that after anything "?" is a query string param. Is there a way to parametrize this with Retrofit?
If I do something like this:
#GET("index.php?/api/v2/get_case/{id}")
Call<TestCase> getTestCase(#Query("id") int id);
I get this exception:
java.lang.IllegalArgumentException: URL query string "/api/v2/get_case/{id}" must not have replace block. For dynamic query parameters use #Query.
Got that...but how can I proceed further using Retrofit?

Solved this through interceptor
Request currentRequest = chain.request();
String finalURL = currentRequest.url().toString().replace("index.php/", "index.php?/");
Request.Builder request = currentRequest.newBuilder()
.addHeader("Authorization", authToken)
.addHeader("Content-Type", ContentType.JSON.toString())
.url(finalURL);

Related

web api (asp.net) - sending data via post method

I'm trying to pass data via post method from my client to a server.
I'm using WebApi to do so.
This i the code i used:
client:
var client = new RestClient();
client.EndPoint = #"http://localhost:57363/hello";
client.Method = HttpVerb.POST;
client.PostData = "{value: Hello}";
var json = client.MakeRequest();
Console.WriteLine(json);
Console.Read();
server:
// POST api/<controller>
public string Post([FromBody]string value)
{
return value + ", world.";
}
The server responds as expected when using postman. However, the client passes a null value instead of the real value.
What am i doing wrong?
First of all a correct json would look like "{value: 'Hello'}".
I use json-online to easily validate such inline json.
On the other hand, I think that you should send just the value in this case, not the entire json (because you are trying to resolve a simple type,a string), so the client should send a request like:
client.PostData = "'Hello'";

adding params in faraday middleware

I am trying to write a middleware that will set additional params to the query string. The use case is to be able to add additional authentication tokens, for eg, to the request as required by the backend, but wanting to inject it independent of the request creation itself.
This is what my middleware(pseudo code) looks like:
class MyMiddleware < Struct.new(:app, :key, :value)
def call(env)
env.params[key] = value #1
#env.params = {key => value} #2
app.call env
end
end
above raises NoMethodError (undefined method[]=' for nil:NilClass)`
above sets the params hash but the parameter is not encoded as part of the query string. The query string remains what it was before the middlewares start processing the request.
My analysis is that since the query string gets built from the params in rack_builder.rb:191
def build_response(connection, request)
app.call(build_env(connection, request))
end
def build_env(connection, request)
Env.new(request.method, request.body,
connection.build_exclusive_url(request.path, request.params), #<== rack_builder.rb:191
request.options, request.headers, connection.ssl,
connection.parallel_manager)
end
Middlewares don't get the opportunity to set additional params. While env has a params property, it is nil and doesn't appear to be touched during or after the middlewares get invoked.
So, I have the following questions:
1. Is there a supported way to achieve this?
2. If not, is there a way to rebuild the query string as part of the middleware executing?
3. Would it be better to defer the URL building to after most of the request middleware chain is executed (but of course, before the adapter gets to do its thing; or do it in the adapter)?
4. Any other options?
Appreciate any guidance.
The answer is here at github: https://github.com/lostisland/faraday/issues/483 by #mislav
Inside the middleware, the request URL is already fully constructed together with all the configured query parameters in a string. The only way to add or remove query parameters is to edit the env.url.query string, e.g.:
MyMiddleware = Struct.new(:app, :token) do
def call(env)
env.url.query = add_query_param(env.url.query, "token", token)
app.call env
end
def add_query_param(query, key, value)
query = query.to_s
query << "&" unless query.empty?
query << "#{Faraday::Utils.escape key}=#{Faraday::Utils.escape value}"
end
end
conn = Faraday.new "http://example.com" do |f|
f.use MyMiddleware, "MYTOKEN"
f.adapter :net_http
end
However, if your middleware is going to be like MyMiddleware above and just add a static query parameter to all requests, the much simpler approach is to avoid the middleware and just configure the Faraday connection instance to apply the same query parameter to all requests:
conn = Faraday.new "http://example.com" do |f|
f.params[:token] = "MYTOKEN"
f.adapter :net_http
end

Get string from current URL

I am writing an asp.net MVC Application. I have the application send a request to FreeAgent and if the request is successful a code is returned in the redirect of the URL.
For example this is a copy of a successful URL.
{
http://localhost:3425/FreeAgent/Home?code=144B2ymEKw3JfB9EDPIqCGeWKYLb9IKc-ABI6SZ0o&state=
}
They have added the ?code=144B2ymEKw3JfB9EDPIqCGeWKYLb9IKc-ABI6SZ0o&state= to my URL
I need the bit after the ?code= and before &state=
I can use this to get the URL
string code = Request.Url.AbsoluteUri;
but I need help extracting the code from this
edit:
The code will be different each time it is run
You can use the System.Uri and System.Web.HttpUtility classes
string uri = "http://localhost:3425/FreeAgent/Home?code=144B2ymEKw3JfB9EDPIqCGeWKYLb9IKc-ABI6SZ0o&state=";
string queryString = new System.Uri(uri).Query;
var queryDictionary = System.Web.HttpUtility.ParseQueryString(queryString);
Then the value of the code query parameter will be available in queryDictionary["code"]

Accessing the query string value using ASP.NET

I have been trying to find the question to my answer but I'm unable to and finally I'm here. What I want to do is access the value passed to a webpage (GET, POST request) using asp.net. To be more clear, for example:
URL: http://www.foobar.com/SaleVoucher.aspx?sr=34
Using asp.net I want to get the sr value i.e 34.
I'm from the background of C# and new to ASP.NET and don't know much about ASP.NET.
Thanx.
Can you refer to this QueryString
Here he says how to access the query string using:
Request.Url.Query
That is not called a Header, but the Query String.
the object document.location.search will contain that and the javascript to get any query string value based on the key would be something like:
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
code from other question: https://stackoverflow.com/a/901144/28004

Send parameters in order in HTTPService

I am trying to work with a simple HTTPService. The problem is that my webservice is conscious of the order of arguments it gets. I will tell the problem with an example:
var service:HTTPService = new HTTPService();
var params:Object = new Object();
params.rows = 0;
params.facet = "true";
service.send(params);
Note that in the above code I have mentioned the parameter rows before facet, but the url I recieve is facet=true&rows=0. So I recieve the argument rows before facet and hence my webservice does not work. I figured out that the contents of array is always sent in alphabetical order, which I dont want.
Is there any way I can achieve explict ordering of parameters sent?
Note that I am not in power of changing the logic of webservice(its basically a RPC service supporting both desktop and web client).
Thanks.
I am assuming you are using a get method. Instead of passing params to the HTTPService, build a url string. You can pass get params just by changing that string then calling the service.
service.url = "originalURL" + "?" + "rows=0" + "&" + "facet=true";
service.send();

Resources