Do not encode parameters in RestSharp - restsharp

I am using RestSharp to access a RubyOnRails API.
As you might know, RoR likes when the parameters names are in the form model_name[property]. RestSharp, on the other hand, does not like it.
Fiddler says I send this to the server :
user%5Bemail%5D=user%40email.com&user%5Bpassword%5D=test
It looks like R# encodes both the parameters and values when it sends the data (unlike Curl, which looks like it encodes selectively).
While that's fine most of the time I guess, in this particular case, it makes the API return a 401 because it doesn't understand the parameters.
Is it possible to ask R# to not encode the request's parameters ?
Thank you !
Edit
Ok, in the R# sources, I found the method RestClient.EncodeParameters, so it looks like the parameter's name is always encoded. I guess I will have to fork it :(

Since RestSharp version 106.4.0 you can just use ParameterType.QueryStringWithoutEncode in request.AddParameter() function:
request.AddParameter("user_id", #"45454545%6565%65", ParameterType.QueryStringWithoutEncode);

I know this has already been answered, but I wanted to add this answer since it worked for me. There is an (albeit hacky) solution to this. Build your own uri for parameters that should not be encoded.
var uri = string.Concat("/path/to/your/api", "?paramThatShouldNotBeEncoded=", DateTime.Now.Date.AddDays(1).ToString("O"));
var restRequest = new RestRequest(uri, Method.GET);

In the RestSharp sources I found out that the parameters are always encoded (both the name and the value), so I guess that I will have to fork it if I want to add an additional parameter.

See this PR from the project site:
https://github.com/restsharp/RestSharp/pull/1157
However, as far as I can tell, it's not yet in a release on NuGet.

Update: probably doesn't work in most cases from comments.
I found an interesting solution... Just decode the parameters you want to pass in and restsharp will encode back to what it should be. For example, I have an api key that uses %7 in it and RestSharper further encodes it. I decoded the api key and passed that into RestSharp and it seems to work!

This solution worked for me
request.AddQueryParameter("sendEndDate", "string:data,something-else", false);
This is the function in the metadata of RestSharp.IRestRequest:
IRestRequest AddQueryParameter(string name, string value, bool encode);

Related

Sending xAPI statements to an LRS

I'm trying to send xAPI statements from an "Activity Provider" to the ADL LRS live demo. The goal is to implement this from my C# .NET application, but I was having trouble implementing it so I tried running a simple POST request from JMeter.
I do get a 200 response, but when I try to check whether the statement was successfully stored at https://lrs.adlnet.gov/me/statements, it's empty.
Am I completely misunderstanding how this structure is supposed to work? I'm going to install the ADL LRS eventually for testing purposes, but I wanted to get the actual request structure worked out first.
The path looks incorrect, the POST should be to {endpoint}/statements, so in your case it looks like it should be https://lrs.adlnet.gov/xAPI/statements. Additionally you should make sure you are setting the X-Experience-API-Version header. If this doesn't solve the issue, you should look at more than just the response status code, and see what the body contains (and add it to your question). The body for the type of request you are sending should return JSON, with an array with a single statement identifier in it. Additionally when you retrieve the statements the URL you use should match the one that you specify when you send, so /me/ is not correct.
If it is a basic C# .NET project you may be interested in https://github.com/RusticiSoftware/TinCan.NET. It is showing its age, but in general for a number of projects it will still work or would at least be a reasonable place to start.

Expo / React Native Basic Authorization

I'm new to React native and Expo, but started to write my own app on it, with the same backend i used with my Cordova app.
Unfortunately i hit a roadblock trying to recreate the btoa() function from browsers, that i use to authenticate users with Basic authorization.
No matter what i try, i can't seem to get the same result as i did with btoa. I tried researching the subject, but i can't find a solid answer what's the difference between Base64.encode() and btoa().
I know i'm doing something wrong. When i try out the post request with Postman, i get the correct Basic auth token with it. But when i do it in code with base64 encoding(tried multiple libraries), the result differs.
Example:
test#test.com:asdasd
in postman: "dGVzdEB0ZXN0LmNvbTphc2Rhc2Rhc2Q="
in app(to utf8, then base64): "W29iamVjdCBBcnJheUJ1ZmZlcl0="
Relevant part of my code:
const utf8_enc = utf8.encode(email+':'+password);
const b64_enc = base64.encode(utf8_enc);
console.log(b64_enc);
Used libraries:
Base64- https://www.npmjs.com/package/base-64
UTF8 - https://github.com/mathiasbynens/utf8.js
Please tell me why are the two different, and how can i recreate the Postman version.
Thank you!
Ok, I see what's happening now. If you follow the docs for that utf8 package, it won't import correctly in React Native. You can see that it's not imported correctly by trying to access decode() or version as both will give you undefined. I think the reason is because they don't support es2015 modules (see this rejected PR). This package will however work fine in Node.js or in the browser.
Oddly enough, you do have access to encode() when you import. It just doesn't do what you think it does. When you attempt to use encode(), all it actually returns is the string: [object ArrayBuffer]. In fact, no matter what string you pass to it, it'll always return the same result. Now if you use btoa() on this string (with or without UTF-8 conversion since there's no difference in this case), you will see that you get that same output in the browser: W29iamVjdCBBcnJheUJ1ZmZlcl0=
So, how to get around this?
If all you expect are extended ASCII strings, then you don't need to encode it in UTF-8 as they will all be within the valid character set. So you can just do:
base64.encode(email+':'+password);
However, if you anticipate supporting all Unicode characters, then you have a few options to convert that string:
Fork the utf8 package to have it support modules/exporting.
Copy paste the entirety of the utf8 source and put it in your own local library and export the functions.
Write your own UTF-8 encoder/decoder using the method suggested here which itself is from the MDN Documentation.
So there's a reference to a solution, here is the relevant encode part of the code from the MDN documentation turned into a function:
function utf8encode(str) {
return encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(
match,
p1
) {
return String.fromCharCode(parseInt(p1, 16));
});
}

WebAPI 2 return types that don't break the help documentation website

Is there a way to use the (apparently preferred) IHttpActionResult return type for my API methods without breaking the super handy help documentation? When I return
List<T>
from my method, I get very descriptive help documentation. When I return IHttpActionResult, I get useless help documentation. Why give us such a cool toy and then suggest that we use something that breaks the toy? Am I missing a great resource for how to use the documentation website together with the MS preferred style?
You should be able to append ResponseTypeAttribute to your action methods which specifies the expected return type when using HttpResponseMessage or IHttpActionResult. This should then be picked up by ApiExplorer when it generates the documentation.
From the website:
Use this to specify the entity type returned by an action when the declared return type is HttpResponseMessage or IHttpActionResult. The ResponseType will be read by ApiExplorer when generating ApiDescription.
If you are using another API to generate the documentation you should check if they support it or include it in the question and maybe someone here knows off hand.

no callback function in cross domain json file

i'm trying to use cross domain jsonp. i have done this before using the callback function in the json file from the other domain. i'm looking at an example json data file that google uses in one of its tutorials:
http://earthquake.usgs.gov/earthquakes/feed/geojsonp/2.5/week -- here obviously the callback function here is eqfeed_callback. in the json file i'm trying to use, there is no callback function that kicks everything off, there is just a bracket [. the file starts off like:
[{"Address":"4441 Van Nuys Blvd","City":"Sherman Oaks" ...
and ends like:
}]
what should i do? is there another way to get at the data without a callback function? i can't edit this file. it's a service that i have a subscription to.
thx.
If it's not your server, and the server doesn't support JSONP, there's no way you can force it to return jsonp. You could try adding ?callback=callback to your url to see if that convinces the server to wrap it in a callback, but if it doesn't, you're out of luck.
Well, almost. There is actually a really dirty hack that you shouldn't use, which is to override javascript's standard Array constructor to assign the contents of the array to a global variable. But that's pretty hideous and I strongly advise against it.
Better ask the maintainer of the service if they're willing to support JSONP. Or better yet, add a CORS header.

Changing/appending request headers in RESTful API in c#

I have a really weird situation (may be its for me only). I developed a RESTful API. By default it returns the result as JSON/XML/TEXT as per the Content Type sent by the client in headers.
Now client is saying that he wants to set the response as default as XML only. What I mean here is that client will not send any content type in headers and it will by default send the request as XML.
When I access this API from browser, it return it as XML but when client's app requests it, it returns JSON result by default. They are getting the result as XML by putting the content type in headers but they don't want to do it and want to have XML result by default.
I hope I am clear on it. If not please let me know.
Any help would be appreciated. Thanks
[Change]
I am interested in knowing if there is some way I can modify the request headers when I receive request on server.
It is in MVC3, C#.
You can't change the request headers, just query them.
I guess you return your result as a simple string in your controllers, isn't it?
And, you are switching between results depending on the contenttype you read from request, don't you?
What is the contenttype the client call come with?
UPDATE:
Look at this page:
http://aleembawany.com/2009/03/27/aspnet-mvc-create-easy-rest-api-with-json-and-xml/
It's a solution for a previous version of MVC, but it will give you an idea about the solution you need:
Adjust the action result depending on the request contenttype
I find the answer and posting here. I just removed the other return types except the xml type like below:
void ConfigureApi(HttpConfiguration config)
{
// Remove the JSON formatter
config.Formatters.Remove(config.Formatters.JsonFormatter);
// or
// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);
}
For more details, please follow below link
http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization
Thanks