POST single string Web API - c#

I'm trying to make an application for Windows which acts like a server for a mobile application (PhoneGap). This application is like a remote for the server application, it invokes methods in which their turn do things.
After long searching and trying to see which components can work together I found OWIN and Web API. So I'm trying to implement this into my application, but I cannot seem to grasp how I can POST a string to invoke methods.
My thought of process is that I POST a string to the server, which it reads and with a switch statement to check the value of the string I know which method to invoke. Very simple, straightforward (not faulty proof probably), but it's a start.
But I cannot seem to get it to work. Here is my controller:
public void Post([FromBody]string value)
{
switch(value)
{
case("buttonOne"):
{
mainClass.pressButtonOne();
break;
}
}
}
I'm using HttpClient to emulate the client on the host pc:
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:6740");
var content = "buttonOne";
var result = client.PostAsync("api/values", content).Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
Console.WriteLine(resultContent);
But this is getting errors, the string isn't a valid HttpContent. But it's always asking for a pair instead of single.

When making POST requests the post content should be of type HttpContent or one of its derived types.
var content = new FormUrlEncodedContent(new Dictionary<string, string> {
{"value" , "buttonOne"} })

Related

Mimic Postman's Post API Request in C# .NET

I am trying to get Autherization Token for TD Ameritrade API using C# .NET. First I get a "CODE" following some steps. Then I use that code in Postman, send the request I get Authorization Code back.
Here is my C# .NET Code to do the same :- (the "CODE" is one time value, can't be re-use. I get a NEW CODE and use that in C# app)
public async Task SignIn(string consumerKey, string code, string redirectUrl = "https://127.0.0.1:4000/TDCallBack/SetCode?code")
{
var path = "https://api.tdameritrade.com/v1/oauth2/token";
using (var client = new HttpClient())
{
var dict = new Dictionary<string, string>
{
{ "grant_type", "authorization_code" },
{ "access_type", "offline" },
{ "client_id", $"{consumerKey}" },
{ "redirect_uri", redirectUrl },
{ "code", code }
};
var req = new HttpRequestMessage(HttpMethod.Post, path) { Content = new FormUrlEncodedContent(dict) };
var res = await client.SendAsync(req);
}
}
But I get "Invalid_Grant" as return, which means API call went to TD Ameritrate server but it did not return the Authorization Token. It could be header/data issue, but no explanation why it did not return an Authorization token.
I think it is a C# programming issue, because TD Ameritrade has a WEB Page (like swagger) to submit API Calls. Exact same API call work with same parameters/values (of course NEW CODE every time). Postman works, TD Ameritrade Website Works BUT my C# Code doesn't work. I will appreciate if I can get some light on this problem. Thanks.
Have you tried using a proxy (like Fiddler) to see what the differences are between the Postman request and request from your code?
That should go a long way towards finding obvious differences. It also looks like you’re not setting the content type to be x-www-form-urlencoded which may be necessary for the endpoint to properly handle the request.
See also: How to POST using HTTPclient content type = application/x-www-form-urlencoded

How to consume Json string from external API? Json returns with escaped or extra characters.

I spent some time trying to figure this one out so I decided to post it here - hopefully it saves some time to someone else.
I'm building an ASP.Net Core Web API MVC application that accepts a Get request and makes a call to an external API (in this case is the Bing Image Search). When returning a result, it would give me a escaped Json string. Example:
"{\"_type\": \"Images\", \"instrumentation\": {\"pageLoadPingUrl\": \"https:...}
Instead of:
{
"_type": "Images",
"instrumentation": {
"pageLoadPingUrl": "https:....
}
Then, I wanted to pass it back to my web client with all sort of non-successes.
I will post shortly how I solved it.
Cheers!
So the issue was that I was trying to process the reponse content the wrong way. All I had to do is user the JsonConvert library.
My full API method looks like this:
[HttpGet("{id}")]
public async Task<IActionResult> Get(string id)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "Enter your key here");
var uri = new Uri("uri to external API here + any parameters");
var response = await client.GetStringAsync(uri);
var jsonResponse = JsonConvert.DeserializeObject(response);
return Ok(jsonResponse);
}
}
Cheers! :)

WebClient - UploadValues : Get Status Response

I'am trying to pass values from a controller to another controller in another domain. I'am adding data to a NameValueCollection and pass it to another controller [httppost] method and receiving data there mapped to a Model same as i passed from.
Currently i'am running it locally by opening two instance of VS simultaneously. When the both VS is opened the values are passed correctly and the information is written to db correctly and i receive a response like "{byte[0]}". Now when i try stopping the destination controller Project and try to submit data then it wont work but still i get the same response as "{byte[0]}". Can somebody please help me how to return the response command in this scenario. Is there a way a understand the UploadValues are completed or not completed.
.........
.........
NameValueCollection resumeDetails = new NameValueCollection();
resumeDetails.Add("FirstName", "KRIZTE");
byte[] res = this.Post(ConfigurationManager.AppSettings["RedirectionUrl"].ToString(), resumeDetails);
return View("Index");
}
public byte[] Post(string uri, NameValueCollection resumeDetails)
{
byte[] response = null;
WebClient client = new WebClient();
response = client.UploadValues(uri, resumeDetails);
return response;
}
You should not use the WebClient because of problems like this.
Microsoft implemented HttpClient class as a newer API and it has these benefits:
HttpClient is the newer of the APIs and it has the benefits of
has a good async programming model
1- being worked on by Henrik F Nielson who is basically one of the inventors of HTTP, and he designed the API so it is easy for you to follow the HTTP standard, e.g. generating standards-compliant headers
2- is in the .Net framework 4.5, so it has some guaranteed level of support for the forseeable future
3- also has the xcopyable/portable-framework version of the library if you want to use it on other platforms - .Net 4.0, Windows Phone etc.
so I'm gonna show you an example of using HttpClient:
var uri = "http://google.com";
var client = new HttpClient();
try
{
var values = new List<KeyValuePair<string, string>>();
// add values to data for post
values.Add(new KeyValuePair<string, string>("FirstName", "KRITZTE"));
FormUrlEncodedContent content = new FormUrlEncodedContent(values);
// Post data
var result = await client.PostAsync(uri, content);
// Access content as stream which you can read into some string
Console.WriteLine(result.Content);
// Access the result status code
Console.WriteLine(result.StatusCode);
}
catch(AggregateException ex)
{
// get all possible exceptions which are thrown
foreach (var item in ex.Flatten().InnerExceptions)
{
Console.WriteLine(item.Message);
}
}

How do I get the destination URL of a shortened URL?

I have an API (https://www.readability.com/developers/api/parser#idm386426118064) to extract the contents of the webapges, but on passing a shortened url or an url that redirects to other, it gives error.
I am developing windows phone 8.1 (xaml) app. Is there any way to get the destination url in c# or any work around?
eg url - http://www.bing.com/r/2/BB7Q4J4?a=1&m=EN-IN
You could intercept the Location header value before the HttpClient follows it like this:
using (var handler = new HttpClientHandler())
{
handler.AllowAutoRedirect = false;
using (var client = new HttpClient(handler))
{
var response = await client.GetAsync("shortUrl");
var longUrl = response.Headers.Location.ToString();
}
}
This solution will always be the most efficient because it only issue one request.
It is possible however, that the short url will reference another short url and consequently cause this method to fail.
An alternative solution would be to allow the HttpClient to follow the Location header value and observe the destination:
using (var client = new HttpClient())
{
var response = client.GetAsync("shortUrl").Result;
var longUrl = response.RequestMessage.RequestUri;
}
This method is both terser and more reliable than the first.
The drawback is that this code will issue two requests instead of one.
You can get the ResponseUri from GetResponse():
string redirectedURL = WebRequest.Create("http://www.bing.com/r/2/BB7Q4J4?a=1&m=EN-IN")
.GetResponse()
.ResponseUri
.ToString();
Interesting article, by the way.
You need to inspect the headers returned from the URL.
If you get HTTP return codes 301 or 302, then you are being notified that the page is redirecting you to another URL.
See http://www.w3.org/Protocols/HTTP/HTRESP.html for more details about HTTP return codes.

Using A Web API for Business Logic?

My web application needs to be able to go and get all my projects from Paymo http://api.paymo.biz/
I am familiar with JSON and XML, but what I'm wondering is, how does one interact with the api (make calls to it).
I would ideally like to make a class in ASP .Net such as PaymoManager(int apikey....)
From there I can wrap the functionality I need. I just need to understand, how do I call functions of the API and how do I get the response. I am not familar with web apis.
Edit: Could you give me an example of this, even with some abstract url. I need this done server side in a CS file.
Basically a simple example that calls someurl.com/somerequest and then how do you receive the JSON or XML... how does this work in terms of a class. I want this in a class.
http://api.paymo.biz/docs/misc.overview.html
To perform an action using the Paymo API, you need to send a request
to the Paymo webservice specifying a method and some arguments, and
will receive a formatted response.
This means that you can use WebClient to download a string from a url:
WebClient client = new WebClient();
string reply = client.DownloadString (address);
Depending on the format you specify, you can parse the reply as XML or JSON.
XDocument xml = XDocument.Parse(reply);
// where ReplyType is a class that defines public
// properties matching the format of the json string
JavaScriptSerializer serializer = new JavaScriptSerializer();
ReplyType abc = serializer.Deserialize<ReplyType>(reply);
If you are using .NET 4.5, you might consider using HttpClient like so:
static async void Main()
{
try
{
// Create a New HttpClient object.
HttpClient client = new HttpClient();
// fill in the details in the following string with your own KEY & TOKEN:
string requestUrl = "https://api.paymo.biz/service/paymo.auth.logout?api_key=API_KEY&format=JSON&auth_token=AUTH_TOKEN"
HttpResponseMessage response = await client.GetAsync(requestUrl );
response.EnsureSuccessStatusCode();
string responseBodyJSON = await response.Content.ReadAsStringAsync();
// Above three lines can be replaced with new helper method in following line
// string body = await client.GetStringAsync(uri);
Console.WriteLine(responseBodyJSON );
// Now you can start parsing your JSON....
}
catch(HttpRequestException e)
{
Console.WriteLine("\nException Caught!");
Console.WriteLine("Message :{0} ",e.Message);
}
}

Categories

Resources