Post values in URL are not set because of special characters in Web API - asp.net-mvc-4

I'm trying to pass a string with special characters to your web api but is giving error.
Below the line where I pass the values ​​pro web api:
string listaParcelaSeparadoVirgula = null;
foreach (var item in listaParcelas)
{
listaParcelaSeparadoVirgula = listaParcelaSeparadoVirgula + ";;" + item;
}
var result = HttpUtility.UrlEncode(listaParcelaSeparadoVirgula);
var response = client.PostAsJsonAsync("api/LancamentoReceitaDespesa/AddLancamentoParcelar/" + result, lancamentoReceitaDespesa).Result;
the result is a string variable with values ​​separated by ";;". Below the contents of the string:
";;aaaaa 1/2||10/01/2014|100,00||;;aaaaa 2/2||10/02/2014|100,00||"
with UrlEncode:
"%3b%3baaaaa+1%2f2%7c%7c10%2f01%2f2014%7c100%2c00%7c%7c%3b%3baaaaa+2%2f2%7c%7c10%2f02%2f2014%7c100%2c00%7c%7c"
Error:
{"Error while copying content to a stream."}
How can I pass these values ​​pro web api?

Well you could try encode value with base64 since in url you could have special symbols
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(result);
var response = client.PostAsJsonAsync("api/LancamentoReceitaDespesa/AddLancamentoParcelar/" + System.Convert.ToBase64String(plainTextBytes), lancamentoReceitaDespesa).Result;
then in web
public void AddLancamentoParcelar(string base64EncodedData) {
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
var result = System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
I am not sure if its the best solution but as you could have any symbol in url then its could be an solution.

Related

Amazon product lookup signature mismatch

This is the response I'm getting: The request signature we calculated does not match the signature you provided.
Here is the code I'm using to generate the signature:
static byte[] HmacSHA256(String data, byte[] key)
{
String algorithm = "HmacSHA256";
KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(algorithm);
kha.Key = key;
return kha.ComputeHash(Encoding.UTF8.GetBytes(data));
}
static byte[] getSignatureKey(String key, String dateStamp, String regionName, String serviceName)
{
byte[] kSecret = Encoding.UTF8.GetBytes(("AWS4" + key).ToCharArray());
byte[] kDate = HmacSHA256(dateStamp, kSecret);
byte[] kRegion = HmacSHA256(regionName, kDate);
byte[] kService = HmacSHA256(serviceName, kRegion);
byte[] kSigning = HmacSHA256("aws4_request", kService);
return kSigning;
}
When I use Amazon's test settings, I get the correct signature
key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
dateStamp = '20120215'
regionName = 'us-east-1'
serviceName = 'iam'
However, when I put my live settings in, I get the not matching error.
Here is what I'm using to get my signature:
var reqSig = getSignatureKey("[my secret key]", dateStamp, "us-west-2","AWSECommerceService");
This is what I'm submitting (I'm just testing it in a browser, for now):
ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[my
access key that corresponds with the secret
key]&Operation=ItemLookup&IdType=UPC&ItemId=635753490879&Timestamp=2019-01-24T19:14:55.2644840Z&Signature=32BA07ECE67F3177BF2EA02923E624D612A45FAA144ED0E43BDDC0DF6574EAC3
I'm not sure if it has to do with the region -- us-west-2 in my case -- because there is no place on the request for a region. I'm not sure how Amazon can test my signature against my parameters if I can't specify what region it is and I've used the region to calculate the signature.
What am I missing?
Ok. After spending days going through this, here is what I had to do:
/*
DOCUMENTATION: https://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html#rest_detailedexample
*/
var itemID = "0679722769";
var accessKeyID = "AKIAIOSFODNN7EXAMPLE";
var timeStamp = DateTime.UtcNow.ToString("o");
var req = $"Service=AWSECommerceService&AWSAccessKeyId={accessKeyID}&Operation=ItemLookup&IdType=UPC&ItemId={itemID}&Version=2013-08-01&Timestamp={timeStamp}";
req = req.Replace(":", "%3A").Replace(",", "%2C"); //UrlDecode certain characters
var reqlist = req.Split('&').ToArray(); //we need to sort our key/value pairs
Array.Sort(reqlist);
req = String.Join("&", reqlist); //join everything back
var reqToSign = $#"GET
webservices.amazon.com
/onca/xml
{req}".Replace("\r", ""); //create the request for signing. We need to replace microsofts's crlf with just a lf; Make sure there are no leading spaces after the linefeeds.
var signage = getSignatureKey("1234567890",reqToSign);
req = $"http://webservices.amazon.com/onca/xml?{req}&Signature={signage}"; //create our request with the signature appended.
return req;
}
private static byte[] HmacSHA256(String data, byte[] key)
{
String algorithm = "HmacSHA256";
KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(algorithm);
kha.Key = key;
return kha.ComputeHash(Encoding.UTF8.GetBytes(data));
}
private static string getSignatureKey(string key, string stringToSign)
{
byte[] kSecret = Encoding.UTF8.GetBytes(key.ToCharArray());
byte[] kSigning = HmacSHA256(stringToSign, kSecret);
return WebUtility.UrlEncode(Convert.ToBase64String(kSigning));
}
Contrary to most of the answers found here and elsewhere, this is the only way that works. The entire request has to be hashed, not just particular parameters. I can't speak to other Amazon services, but the Commerce Service has to be done like this.
Quite a few answers referenced this: https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html or this: Amazon API generating a request signature in C# .NET
As I stated in my question, this is most certainly not correct. If you're not passing a region parameter, how can Amazon create the same signature since it doesn't have all the information.
Anyway, this works now.

Web Search API from Contextual Web Search Engine

How to parse in C# or Python the JSON response returned from Contextual Web search api?
(here is a link to the request: http://contextualwebsearch.com/freeapi)
Here is the code in C# for consuming the API using the RapidAPI marketplace.
/// <summary>
/// Performs a Web search and return the results as a SearchResult.
/// </summary>
private static void MaShapeParsingExample()
{
// **********************************************
// *** Update or verify the following values. ***
// **********************************************
//Step 1. Replace the following string value with your valid X-Mashape-Key key.
string Your_X_Mashape_Key = "OV5vB1qRFnmsh2GYXgVtmjbIfLzup1JXrVjjsntqzb3T25JWCA";
//Step 2. The query parametrs:
int count = 10; //the number of items to return
string q = "Donald Trump"; //the search query
bool autoCorrect = true; //autoCorrectspelling
//Step 3. Perform the Web request and get the response
var response = Unirest.get(string.Format("https://contextualwebsearch-websearch-v1.p.mashape.com/api/Search/WebSearchAPI?q={0}&count={1}&autocorrect={2}", q, count, autoCorrect))
.header("X-Mashape-Key", Your_X_Mashape_Key)
.header("X-Mashape-Host", "contextualwebsearch-websearch-v1.p.mashape.com")
.asJson<string>();
//Step 4. Get the ResponseBody as a JSON
dynamic jsonBody = JsonConvert.DeserializeObject(response.Body);
//Step 5. Parse the results
//Get the numer of items returned
int totalCount = (int)jsonBody["totalCount"];
//Get the list of most frequent searches related to the input search query
List<string> relatedSearch = JsonConvert.DeserializeObject<List<string>>(jsonBody["relatedSearch"].ToString());
//Go over each resulting item
foreach (var webPage in jsonBody["value"])
{
//Get The web page metadata
string url = webPage["url"].ToString();
string title = webPage["title"].ToString();
string description = webPage["description"].ToString();
string keywords = webPage["keywords"].ToString();
string provider = webPage["provider"]["name"].ToString();
DateTime datePublished = DateTime.Parse(webPage["datePublished"].ToString());
//Get the web page image (if exists)
string imageUrl = webPage["image"]["url"].ToString(); //get the webpage image url
int imageHeight = (int)webPage["image"]["height"]; //get the webpage image height
int widthHeight = (int)webPage["image"]["width"]; //get the webpage image width
//An example: Output the webpage url, title and published date:
Console.WriteLine(string.Format("Url: {0}. Title: {1}. Published Date:{2}.",
url,
title,
datePublished));
}
}

Sending sms to multiple phonenumbers using mysms API

I'm trying to send sms using mysms API. I am able to send to single number using following example:
Example: https://api.mysms.com/json/message/send?api_key=xxxxx&msisdn=xxx&password=xxx&recipient=436761234567&message=Hi
How can I send to multiple number using above example?
I came up with this code:
function sendSMS() {
var apikey = "your api_key";
var mno = 40123123456; // msisdn = your number without +sign in from
var pwd = "yourpassword";
// var no = 40123123456; // single number & replace this with a real one
var grp = [40123123456,40123123456,40123123456]; // multiple numbers / let's call it a group & just replace those with your actual testing numbers
var msg = "Hi!%0aThis is a test message!%0aThis is another row.%0a:D"; // Use %0a to insert a new row in your message
for ( var i in grp ) {
var smsurl = "https://api.mysms.com/json/message/send?api_key="+apikey+"&msisdn="+mno+"&password="+pwd+"&recipient="+grp[i]+"&message="+msg+"";
var xhttp = new XMLHttpRequest();
xhttp.open("GET", smsurl, true);
xhttp.send();
console.log(smsurl);
}
}
Now just make the call:
sendSMS();
This code is javascript and I hope will answer your question well. Also it was tested and proven that is working. There is always room for improvements.

sending string parameter in action=track leanplum Rest Api not working

I want to send string parameters in Leanplum api using action script
Eg param:{"Element":"Hi"}
var request:URLRequest = new URLRequest("https://www.leanplum.com/api");
request.method = URLRequestMethod.GET;
var variables:URLVariables = urlVariables;
variables.userId = userId;
variables.event = eventName;
var params:Object = new Object();
params.Element = "Hi";
var paramStr:String = JSON.stringify(params);
variables.params = paramStr;
variables.appId = appId;
variables.clientKey = clientKeyProduction;
variables.apiVersion = apiVersion;
variables.action = "track";
variables.versionName = AppInfo.getInstance().appVersion;
request.data = variables;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, function(e:Event):void {
trace(e.target.data);
});
loader.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void {
trace(e.target.data);
});
loader.load(request);
This is actual Request (App ID and ClientKey are dummy):
https://www.leanplum.com/api?clientKey=V42fKaJaBuE&userId=1010&params={"Element":"Ur"}&appId=HEVdDlXiBVLwk&event=Element_Opened&action=track&versionName=2.3.0&apiVersion=1.0.6&info=Lu
Encoded Request:
https://www.leanplum.com%2Fapi%3FclientKey%3DV42fKaJaBuE%26userId%3D1010%26params%3D%7B%22Element%22%3A%22Ur%22
%7D%26appId%3DHEVdDlXiBVLwk%26event%3DElement_Opened%26action%3Dtrack%26versionName%3D2.3.0%26apiVersion%3D1.0.6%26info%3DLu
if I run above request in any rest client I get the same status success : true .
I am getting the response {"response": [{"success": true}]} but I can't find the parameters with value string in Leanplum dashboard, its listing parameter name but not the String Value for parameter.
If you apply some combination of filters then you can see values of parameter you sent to leanplum. like First select the occurrence of some event then apply Group by parameter then select parameter you want to see the data for.
Its a little different from flurry, Google analytics etc.

Index (zero based) must be greater than or... Working with the Bit.ly API

I'm working (actually more like playing) around with the Bit.ly API, and keep getting the error in the title of this question. So I'm going to show you the code and hopefuly someone can help me resolve this. First the client side code.
var x = service.GetClicks(url, service.BitlyLogin, service.BitlyAPIKey);
Console.WriteLine(x);
Console.ReadLine();
And this is the code that's being called
public List<int> GetClicks(string url, string login, string key)
{
List<int> clicks = new List<int>();
url = Uri.EscapeUriString(url);
string reqUri =
String.Format("http://api.bit.ly/v3/clicks?" +
"login={0}&apiKey={1}&shortUrl={2}&format=xml" +
login, key, url);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
req.Timeout = 10000; // 10 seconds
Stream stm = req.GetResponse().GetResponseStream();
XmlDocument doc = new XmlDocument();
doc.Load(stm);
// error checking for xml
if (doc["response"]["status_code"].InnerText != "200")
throw new WebException(doc["response"]["status_txt"].InnerText);
XmlElement el = doc["response"]["data"]["clicks"];
clicks.Add(int.Parse(el["global_clicks"].InnerText));
clicks.Add(int.Parse(el["user_clicks"].InnerText));
return clicks;
}
As you can see it's very simple code, nothing complicated, and I can see nothing that causes this error. Anyone out there who has worked with(the full error is Index (zero based) must be greater than or equal to zero and less than the size of the argument list.) the Bit.ly API and can lend a hand?
Instead this
string reqUri =
String.Format("http://api.bit.ly/v3/clicks?" +
"login={0}&apiKey={1}&shortUrl={2}&format=xml" + login, key, url);
Use this
string reqUri = String.Format("http://api.bit.ly/v3/clicks?login={0}&apiKey={1}&shortUrl={2}&format=xml", login, key, url);
Notice that I just changed the plus sign with the comma before "login, key, url);" at the end of the String.Format().
I narrowed it down to a place where I was using string.Format to build an array and has less in the string.Format than what was supposed to. I had it go to Index 3 but only filled to Index 2
Not for your specific case, but I ran into this: make sure that, if you have multiple parameters, you send them as an array of objects instead of an IEnumerable:
IEnumerable<object> myArgs = ...;
string toFormat = "{0} xyz {1}";
String.Format(toFormat, myArgs);
// ERROR, since myArgs is one argument whereas the string template requires two
String.Format(toFormat, myArgs.ToArray());
// Valid, as the Format() accepts an array of objects to fill all arguments in the string