C# HTTPClient Not Sending Request - c#

I have a WPF application where I need to retrieve configuration data from a remote API. The API has been tested and is working correctly returning what I believe to be the correct format. I have created a data type for the response etc etc but when I get to the line getting the response via the HttpClient it doesn't send any request to the API.
DataType :-
public class Mylist
{
public string ItemName { get; set; }
public string ItemText { get; set; }
public string ConfigName { get; set; }
public string ConfigValue { get; set; }
public string ConfigType { get; set; }
}
Code :-
string licKey = ConfigManager.GetSetting("Lic");
string Uri = ConfigManager.GetSetting("API");
string UserAPI = ConfigManager.GetSetting("Config");
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(Uri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync(UserAPI + "?Licence=" + licKey);
var data = await response.Content.ReadAsAsync<IEnumerable<Mylist>>();
int count = 0;
List<Mylist> nudges = new List<Mylist>((IEnumerable<Nudgelist>)data);
// Do something with the data
the code builds the correct URL (https://example.com/api/Uri?Licence=licencevalue) for the request and if input manually into the browser it gives a response as per the below :-
<Mylist>
<ConfigName>cName</ConfigName>
<ConfigType>cType</ConfigType>
<ConfigValue>cValue</ConfigValue>
<ItemName>iName</NudgeName>
<ItemText>iText</NudgeText>
</Mylist>
<Mylist>
...
</Mylist>
When I run the code above and step through it then we get to the line "var response = await client.GetAsync(UserAPI + "?Licence=" + licKey);" and it just skips the rest of the code and moves onto the next call, no error raised or failures anywhere to be found.
I have run logs on the API and we are not seeing the request coming in, if we use an identical model of code for calling another API controller to call Uri2 (https://example.com/api/Uri2?Licence=licencevalue) it works fine.

Try this
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<IEnumerable<MyList>>(stringData);
}
else
{
var statusCode= response.StatusCode);
}

Related

C#- http client response help request

I have the following code:
static async Task checkIMEI( double IMEI)
{
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://kelpom-imei-checker1.p.rapidapi.com/api?service=model&imei=" + IMEI.ToString() ),
Headers =
{
{ "X-RapidAPI-Host", "kelpom-imei-checker1.p.rapidapi.com" },
{ "X-RapidAPI-Key", "key" },
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
object result = await response.Content.ReadAsStringAsync();
MessageBox.Show("\n" + result);
}
}
Running this code I get the following
response
I would like to further break up this response and the individual data and assign it to a variable such as
string ModelNum= model_nb >> should show "SM-G891A"
String Brand = brand >> should show "Samsung Korea"
Your help would be appriciated.
first your Client is bad practice use this link HttpClientFactory Microsoft docs to refactor your client.
Then Create Class for your needed model for ex:
public class Mobile
{
public string ModelNum { get; set; }
public string Brand { get; set; }
}
then you should deserialize your result to your model:
var result = await response.Content.ReadAsStringAsync();
var model = JsonSerializer.Deserialize<Mobile>(result);

How do I retrieve and use data I get with Http GET Requests in c#

So I am trying to use GET requests with c# but nothing is really working out.
I wanted to use the site https://covid19.mathdro.id/api as a test to see if I can get the info out of there and use it in a windows form. But I can't seem to figure out how. The only guides I found weren't really that helpful and it just confused me more. Would anyone be able to help me out?
I have tried to use the HttpClient with JSON.net but I get confused in it.
Been trying for the past 2 hours since I never dealt with HTTP GET Requests in c# other than with Python.
Install the 'Newtonsoft.Json' nuget package.
async Task<JToken> GetREST(string uri)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(uri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP GET
HttpResponseMessage response = await client.GetAsync("");
if (response.IsSuccessStatusCode)
{
var jsonData = await response.Content.ReadAsStringAsync();
return JToken.Parse(jsonData);
}
}
return null;
}
async private void button1_Click(object sender, EventArgs e)
{
var jObj = await GetREST("https://covid19.mathdro.id/api");
var confirmed = jObj["confirmed"];
Console.WriteLine("Confirmed:" + confirmed["value"]);
var confirmedJSON = await GetREST(confirmed["detail"].ToString());
Console.WriteLine(confirmedJSON);
}
In addition to the accepted answer, you can always work with the data as objects by deserializing - I prefer this method over using JToken etc as it tends to be very easy to work with the objects (there's often less boilerplate to pull bits of data from the response).
public async Task<CovidData> GetCovidData(string uri)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(uri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("");
if (response.IsSuccessStatusCode)
{
var jsonData = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<CovidData>(jsonData);
}
}
return null;
}
The objects you'd deserialize to would look like this:
public class CovidData
{
public ValueDetailPair Confirmed { get; set; }
public ValueDetailPair Recovered { get; set; }
public ValueDetailPair Deaths { get; set; }
}
public class ValueDetailPair
{
public int Value { get; set; }
// If you need the link to the detail it would be deserialized to this string member
public string Detail { get; set; }
}
It really does depend on preference and your use case though.
example:
var data = await GetCovidData("https://covid19.mathdro.id/api");
Console.WriteLine(data.Confirmed.Value);
Console.WriteLine(data.Confirmed.Detail);
Console.WriteLine(data.Recovered.Value);

JSON in body of POST then extract the body of the response to get the access_token

I have this small Python application that I wrote last year that I need to remake in C#. I don't really know C#, but need to make a connection between Dynamics 365 and QuickBooks Desktop which uses C# (or C++, Java, VB... none of which I know).
As I said, the Python app works fine, and I get what I need from D365 via Postman, put having a hell of time getting it working for C#. There is a sample project here, but trying to interpret what is going on is making my head spin (it doesn't run either otherwise I'd just use it).
This is what I currently do:
class Program
{
static void Main(string[] args)
{
ConnectToCRM();
}
static void ConnectToCRM()
{
string crmOrg = "https://company.api.crm.dynamics.com";
string clientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
string clientSecret = "super_secret_stuff";
string username = "me#company.biz";
string userPassword = "password";
string authorizationEndPoint =
"https://login.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/oauth2/authorize";
string crmWebApi = "https://company.api.crm.dynamics.com/api/data/v8.2";
var values = new Dictionary<string, string>
{
{"client_id", clientId},
{"client_secret", clientSecret},
{"resource", crmOrg},
{"oauthUrl", authorizationEndPoint},
{"username", username},
{"password", userPassword},
{"grant_type", "password"}
};
HttpRequestToCrm(values);
}
public class ServerResponse
{
public string token_type { get; set; }
public string scope { get; set; }
public string expires_in { get; set; }
public string ext_expires_in { get; set; }
public string expires_on { get; set; }
public string not_before { get; set; }
public string resource { get; set; }
public string access_token { get; set; }
public string refresh_token { get; set; }
}
static async void HttpRequestToCrm(Dictionary<string, string> values)
{
string tokenEndPoint = "https://login.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/oauth2/token";
var client = new HttpClient();
var content = new FormUrlEncodedContent(values);
try
{
HttpResponseMessage response = await client.PostAsync(tokenEndPoint, content);
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(response);
Console.WriteLine(responseContent);
ServerResponse rb = JsonConvert.DeserializeObject<ServerResponse>(responseContent);
Console.WriteLine(rb.token_type);
}
catch (WebException e)
{
Console.WriteLine("catch");
Console.WriteLine(e);
throw;
}
}
}
As I understand it I need to be using FormUrlEncodedContent for x-www-form-urlencoded, as x-www-form-urlencoded is what I have to do in Postman for it to work. Python just seems to be doing it.
Console.WriteLine(content); just says System.Net.Http.FormUrlEncodedContent. The Console.WriteLine(response); actually has something in it now, where it didn't before: System.Threading.Tasks.Task1[System.Net.Http.HttpResponseMessage]. I need to get the response body, so that I can get theaccess_token` and then finally actually query the D365 web API.
How do I get the response body and the access_token? How do I even see that that is what it is responding with? Is my approach entirely wrong?
EDIT:
Whether or not I do:
HttpResponseMessage response = await client.PostAsync(tokenEndPoint, content);
Or:
var response = await client.PostAsync(tokenEndPoint, content);
Visual Studio Community 2017 quits running at that line and doesn't trigger any kind of error. I'll sent a break point there, then F10 or F11, and it exits the program.
Found this regarding it:
Code Execution stops with no error
Turned on all the options, but still can't see why it is just ending.
This is a screenshot of what I'm trying to do working in Postman. I'm obviously just doing something wrong in C#.
Try this to get the Content of the Response:
HttpResponseMessage response = await client.PostAsync(tokenEndPoint, content);
if(!response.IsSuccessStatusCode) return; // optional
string responseContent = await response.Content.ReadAsStringAsync();
First of all you need to await the PostAsync() call. Since this only leaves you with a HttpResponseMessage then and not the actual content of the response, you'd have to get it in a second step by reading the response's Content Property as a string.
If your Response returned an OK (HTTP 200 Status Code) this code should leave you with responseContent holding the desired response as a string.
I assume that your access_token is a JSON Property in this received string, so you would have to then deserialize it or use a extracting mechanism to get the actual access_token from said string. There are already plenty of posts on StackOverflow regarding this, so i won't elaborate on it any further.
Couple things right off the bat, you aren't awaiting your PostAsync call so you don't really have the response stored.
Second, C# doesn't automatically serialize objects like that when you tell it to write to the console so it is just telling ou what kind of object it is, aka a task that is wrapping an HttpResponseMessage.
The following should get you the response body (assuming it is just the token this will work fine for you). You'll need to modify it some to work perfectly for you, but this should get you started.
try
{
var response = await client.PostAsync(tokenEndPoint, content);
//read the response body as a string here
string token = await response.Content.ReadAsStringAsync();
Console.WriteLine(response);
}
catch (WebException e)
{
Console.WriteLine("catch");
Console.WriteLine(e);
throw;
}

C# - PostAsync response returning empty array

I am writing a mobile application in Xamarin.Forms, and have a very simple PHP file for my back end. The mobile application sends a post request to the PHP file, and the PHP file is meant to var_dump the post contents.
<?php
echo "Your post response is...";
var_dump($_POST);
?>
My Xamarin application uses the HttpClient class to create a simple post request using the PostAsync() method.
public class RestService
{
HttpClient client;
private const string URL = "https://braz.io/mobile.php";
public RestService()
{
client = new HttpClient();
client.MaxResponseContentBufferSize = 256000;
}
public async Task<string> getUserInformation()
{
User u = new User("Barns", "password1234", "email#email.com");
string json = JsonConvert.SerializeObject(u);
var uri = new Uri(string.Format(URL, string.Empty));
try
{
client.DefaultRequestHeaders.Add("Accept", "application/json");
StringContent s = new StringContent(json);
var response = await client.PostAsync(uri, s);
string body = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{Console.WriteLine(ex);}
return null;
}
}
For some reason, my post request is only getting the response Your post resonse is... followed by an empty array. It is strange, because when I use PostMan on google chrome, it returns the correct information.
I have checked that my json variable has valid JSON in it as well, so I am unsure why the PostAsync function is returning/sending an empty array from/to my PHP file.
UPDATE as per comment request
The JSON I am sending is as follows:
"{\"username\":\"Barney\",\"password\":\"1234\",\"email\":\"email#email.com\"}"
My user class is:
public class User
{
public User(){ }
public string username { get; set; }
public string password { get; set; }
public string email { get; set; }
public User(string username, string password, string email)
{
this.username = username;
this.password = password;
this.email = email;
}
}
The issue has nothing to do with the Xamarin side of things. Your issue lies in the PHP code you provided and the fact that when you tried sending something with POSTman, you didn't send it as the body of the request.
In order to read the request body, you need to read the input stream:
$json = file_get_contents('php://input');
Then you can output that with
var_dump($json);
As for your RestService code, I would advise you to provide the content type for your string content:
var s = new StringContent(json, Encoding.UTF8, "application/json");

RegisterUser via WebApi from WPF Application

I wish my WPF application to communicate with a webapi I'm in the process (once I get past this) of writing. I've never connected to two up before and I'm struggling to perform the most basic of functions, to register a user.
I'm using the standard MVC + WebApi implementation from VS 2013 with individual accounts.
I'm looking at other SO code spinets to understand how to connect the two, but I keep getting bad request back when I call API.
I've tried two different methods to format the JSON, without success.
Where am I going wrong?
public async void RegisterUser()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:2045/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var rbm = new RegisterBindingModel();
rbm.UserName = "someemail";
rbm.Password = "somepassword";
rbm.ConfirmPassword = "somepassword";
//MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
//HttpContent content = new ObjectContent<RegisterBindingModel>(rbm, jsonFormatter);
//var resp = client.PostAsync("api/Account/Register", content).Result;
var response = await client.PostAsJsonAsync("api/Account/Register", rbm);
}
}
public class RegisterBindingModel
{
public string UserName { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
ok, the problem with trying to use other peoples code from SO to learn is that it sometimes has mistakes of its own.
Changed the model to
public string Email { get; set; }
now works great :)

Categories

Resources