c # send parameters when sending json get request - c#

I'm working on an application to make api get, post, delete, update requests on c # windowsforms.
My problem is: I want to send a parameter in "Body" when requesting a get. How can I do that ?
using System.Net.Http;
using System;
using System.Threading.Tasks;
using HastaTakip.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text;
namespace HastaTakip.Api
{
public class CustomersRepository
{
public HttpClient _client;
public HttpResponseMessage _response;
public HttpRequestMessage _requestMessage;
public CustomersRepository()
{
_client = new HttpClient();
_client.BaseAddress = new Uri("http://localhost:3000/");
_client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZ0aG1seW16QGhvdG1haWwuY29tIiwidXNlcklkIjoxLCJpYXQiOjE2MTM5MDY5NDMsImV4cCI6MTYxNDA3OTc0M30.NER1RMTYx41OsF26pjiMXY-pLZTE-pIg4Q73ehwGIhA");
_client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<CustomersModel> GetList()
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("business_code", "dental")
});
_response = await _client.GetAsync(content);
var json = await _response.Content.ReadAsStringAsync();
var listCS = CustomersModel.FromJson(json);
return listCS;
}
}
}

to send a GET request with a JSON body:
HttpClient client = ...
...
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("some url"),
Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
But HTTP GET with a body is a somewhat unconventional construct that falls in a gray area of the HTTP specification!

You better create a class for your content data:
public class RequestData
{
pubic string BusinessCode {get; set;}
{
After this you can create your content object
public async Task<CustomersModel> GetList()
{
var data=new RequestData{BusinessCode="dental"}
var stringData = JsonConvert.SerializeObject(data);
contentData = new StringContent(stringData, Encoding.UTF8, "application/json");
var response = await _client.GetAsync(contentData);
// but I am not sure that Get will work correctly so I recommend to use
var response = await _client.PostAsync(contentData);
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<CustomersModel>(stringData);
}
else
{
....error code
}
}

Related

GraphQL request in C#

I'm a Unity developer tool and i want to post a GraphQL request with using System.Net.Http; (i don't want to use the GraphQL dll because there are compatibility problems).
But i have this error (got on the Debug.Log) :
POST body missing, invalid Content-Type, or JSON object has no keys.
My code :
static async Task<string> getEntityID(string path)
{
var values = new Dictionary<string, string>
{
{ "query", "query {topLevelEntityTypes {id}}" },
{ "variables", "{}" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://localhost:4000/graphql", content);
var responseString = await response.Content.ReadAsStringAsync();
Debug.Log(responseString);
return responseString;
}
Thank you !
Solution by ProgrammingLlama :
static async Task<string> getEntityID(string path)
{
var myObject = new QueryJson();
myObject.query = "query {topLevelEntityTypes {id}}";
myObject.variables = "{}";
var response = await client.PostAsync("http://localhost:4000/graphql", new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(myObject), Encoding.UTF8, "application/json"));
var responseString = await response.Content.ReadAsStringAsync();
Debug.Log(responseString);
return responseString;
}
Class json
internal class QueryJson
{
public string query { get; set; }
public string variables { get; set; }
}

How would i send a payload with my post request in c#?

I am trying to login to a website and i need to send the credentials as a payload but I don't understand how payloads are sent.
public class LoginClient
{
private readonly HttpClient _client;
public LoginClient()
{
_client = new HttpClient();
}
public async Task Put()
{
using (var request = new HttpRequestMessage(HttpMethod.Post, $"https://accounts.nike.com/challenge/password/v1"))
{
using (var response = await _client.SendAsync(request))
{
}
}
}
}
You are trying to send Json, use PostAsync to set the content
var client = new HttpClient();
var url = $"https://accounts.nike.com/challenge/password/v1";
var data = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, data);

Get a custom answer, an object for an HTTP Post request in a Web API

I call this WebApi endpoint:
public IActionResult MyEndPoint([FromBody] MyType myType)
{
// I do some stuff
var answer = new MyAnswer { Id = Guid.NewGuid() };
return Ok(answer);
}
The call to call the endpoint is this:
public async Task<string> httpPost(string url, string content)
{
var response = string.Empty;
using(var client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(url),
Content = new StringContent(content, Encoding.UTF8, "application/json")
};
HttpResponseMessage result = await client.SendAsync(request);
if(result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString(); //here
}
}
return response;
}
I'd like to have access MyAnswer object returned with the Ok() where the //here is. I put a breakpoint but nothing look like my object.
public async Task<MyAnswer> HttpPost(string url, string content)
{
var response = new MyAnswer();
using (var client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(url),
Content = new StringContent(JsonSerializer.Serialize(content), Encoding.UTF8, "application/json")
};
HttpResponseMessage result = await client.SendAsync(request);
if (result.IsSuccessStatusCode)
{
var responseString = await result.Content.ReadAsStringAsync();
response = JsonSerializer.Deserialize<MyAnswer>(responseString, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
}
return response;
}

Returning JSON via WebApi

I am using the HttpClient in C# to try and integrate SSO (Single Sign On) into some of our custom Applications.
I have done this successfully in our JavaScript Apps, but I'm having some difficulty integrating it into some of our Umbraco sites.
My code so far:
using System;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web;
using System.Web.Http;
using Newtonsoft.Json;
using System.Collections.Generic;
using Umbraco.Web;
using Umbraco.Web.WebApi;
namespace Umbraco.WebApi
{
public class TestController : UmbracoApiController
{
public HttpClient client = new HttpClient();
[HttpPost]
public async Task<Object> GetRefreshToken(Token t)
{
try {
string refToken = t.refresh_token;
var values = new Dictionary<string, string>
{
{ "grant_type", "refresh_token" },
{ "client_id", "CLIENTID" },
{ "client_secret", "CLIENTSECRET" },
{ "refresh_token", refToken }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://URL.org/Token", content);
string responseString = await response.Content.ReadAsStringAsync();
return responseString;
} catch(HttpRequestException e) {
return e;
}
}
public class Token
{
public string refresh_token { get; set; }
}
public class AuthData
{
public string access_token { get; set; }
public string token_type { get; set; }
public int expires_int { get; set; }
public string refresh_token { get; set; }
public string userName { get; set; }
public string client_id { get; set; }
public DateTime issued { get; set; }
public DateTime expires { get; set; }
}
}
}
Which does successfully return the data I'm after but there are issues with the returned data (Removed sensitive data):
<z:anyType xmlns:d1p1="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" i:type="d1p1:string">
{"access_token":"XXXXXXXX","token_type":"bearer","expires_in":1199,"refresh_token":"XXXXXX","userName":"XXXXXX","as:client_id":"XXXXX",".issued":"Fri, 20 Sep 2019 13:23:48 GMT",".expires":"Fri, 20 Sep 2019 13:43:48 GMT"}
</z:anyType>
It also seems to be getting returned as XML instead of JSON?
C# is not my strongest of languages, so I may be completely wrong.
Any help appreciated.
In your code, after you get the JSON string responseString, instead of returning it, try the following code.
...
string responseString = await response.Content.ReadAsStringAsync();
response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(responseString, Encoding.UTF8, "application/json");
return response;
You need to change your method return value from Task<Object> to Task<HttpResponseMessage>
Edit:
To access the properties, install the Newtonsoft.Json package and try below code.
var jsonString = ...
JObject jo = JObject.Parse(jsonString);
Console.WriteLine(jo["access_token"]);
One of the things you can do to resolve this is to specifically request a json format on your response by adding the corrent request headers
Accept: application/json
try it like so
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Now if the server pays attentions to the request headers it will return a json back to you.
It might be defaulting to xml because there is no such header in your request OR the server only supports returning xml responses.
EDIT: If you can not get the server to return json, you can convert your xml string response to json string. Take a look at this example. After the convertsion you can return your json string normally from your controller.
Edit:
Ok, try out this sample below:
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("client_id", ""),
new KeyValuePair<string, string>("scope", ""),
new KeyValuePair<string, string>("grant_type", "authorization_code"),
new KeyValuePair<string, string>("redirect_uri", ""),
new KeyValuePair<string, string>("code", ""),
new KeyValuePair<string, string>("client_secret","")
});
AADTokenResponse TokenResponse = null;
string _baseAddress = string.Format("https://yourTargetDomain.com/");
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_baseAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var responseMessage = await client.PostAsync("targetApiSegment", content);
if (responseMessage.IsSuccessStatusCode)
{
var responseString = await responseMessage.Content.ReadAsStringAsync();
TokenResponse = JsonConvert.DeserializeObject<AADTokenResponse>(responseString);
}
}
I think in this case, FormUrlEncodedContent is the wrong choice, and you'd want to use StringContent instead, similar to this:
var content = new StringContent(HttpUtility.UrlEncode(values), Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://URL.com/Token", content);
The reason being, I dont think FormUrlEncodeContent has an overload to accept adding content type.
Another alternative would be to switch to using SendAsync rather than PostAsync, as SendAsync has some additional flexibility.

How to post a long string containing XML to Web API

I'm trying to post a long string (containing XML) to my Web API controller, but I'm failing miserablely.
The following works if TextAsXml is short, but when TextAsXml is long it fails "Invalid URI: The Uri string is too long.", which is understandable.
// Client code
using (var client = new HttpClient())
{
var requestUri = "http://localhost:49528/api/some";
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("Author", "John Doe"),
new KeyValuePair<string, string>("TextAsXml", "<?xml version=\"1.0\" encoding=\"UTF-8\"?><note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>")
});
var response = client.PostAsync(requestUri, content).Result;
response.EnsureSuccessStatusCode();
}
// Controller code
public HttpResponseMessage Post(SomeModel someModel)
{
// ...
return Request.CreateResponse(HttpStatusCode.OK);
}
public class SomeModel
{
public string Author { get; set; }
public string TextAsXml { get; set; }
}
How do I get the above code to work when TextAsXml is long? I tried playing around with StringContent and MultipartContent, but couldn't get it to work.
// This results in 500 Internal server error.
using (var client = new HttpClient())
{
var requestUri = "http://localhost:49528/api/some";
var textAsXml = File.ReadAllText("Note.xml");
var content = new MultipartFormDataContent();
content.Add(new StringContent("John Doe"), "Author");
content.Add(new StringContent(textAsXml), "TextAsXml");
var response = client.PostAsync(requestUri, content).Result;
response.EnsureSuccessStatusCode();
}
Send the XML as content without Uri encoding.

Categories

Resources