I have two textboxes and a button. I want to put something in textBox1, send that to a server and put the results I get back in textBox2.
I can't seem to understand sockets well enough to accomplish this. I have an address and a port.
Does anyone have just a super simple setup to do this? Everything I've found includes classes I can't even find namespaces for.
Thanks!
Here is a simple solution to get data from a website:
private static HttpClient _client = new HttpClient();
public static async Task<string> GetWebsiteDataAsync(Uri fromUri)
{
using (var msg = new HttpRequestMessage(HttpMethod.Get, fromUri))
using (var resp = await _client.SendAsync(msg))
{
resp.EnsureSuccessStatusCode();
return await resp.Content.ReadAsStringAsync();
}
}
You would then call it as so:
var websiteData = await GetWebsiteDataAsync(new Uri("https://example.com"));
Your title asked for Post as well, so here's how you'd do that (requires Newtonsoft.Json nuget package):
public static async Task<TResult> PostObjectToWebsiteAsync<TResult>(
Uri site, object objToPost)
{
using (var req = new HttpRequestMessage(HttpMethod.Post, site))
{
req.Content = new StringContent(JsonConvert.SerializeObject(objToPost),
Encoding.UTF8, "application/json");
using (var resp = await _client.SendAsync(req))
{
resp.EnsureSuccessStatusCode();
using (var s = await resp.Content.ReadAsStreamAsync())
using (var sr = new StreamReader(s))
using (var jtr = new JsonTextReader(sr))
{
return new JsonSerializer().Deserialize<TResult>(jtr);
}
}
}
}
And you could call that like this:
var objToPost = new
{
hello = "world",
value = 5
}
var postResonse = await PostObjectToWebsiteAsync<object>(
new Uri("https://example.com"), objToPost);
Related
I use a strange API that sends JSON objects in kind of chunks (line by line).
I need to be able to read each line of the response to my request asynchronously. I'm already trying to display in the console each of these requests.
The code below is the main one (the main{} function only calls this function). I want this code to be executed asynchronously too, that's why the function is declared as async task.
When I launch the application, the query runs fine, but the program doesn't display the lines one by one: it waits for the end of the query to display everything at once.
I'm very new to async/streams, sorry if the code is so bad.
public async Task test()
{
HttpClient client = new HttpClient();
var values = new Dictionary<string, string> // POST data
{
{ "api", "v2" },
{ "field1", "data1" },
{ "field2", "data2" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://api.domain/post", content);
using (var theStream = await response.Content.ReadAsStreamAsync())
{
StreamReader theStreamReader = new StreamReader(theStream);
string theLine = null;
while ((theLine = await theStreamReader.ReadLineAsync()) != null)
{
Console.WriteLine("----- New Line:"); //Just for the eyes
Console.WriteLine(theLine);
}
};
}
You are missing HttpCompletionOption.ResponseHeadersRead, which will only block while reading the headers, and the content comes through asynchronously. You must use SendAsync and a HttpRequestMessage for this.
Also you are missing some using blocks, and HttpClient should be cached in a static field.
static HttpClient _client = new HttpClient();
public async Task test()
{
var values = new Dictionary<string, string> // POST data
{
{ "api", "v2" },
{ "field1", "data1" },
{ "field2", "data2" }
};
using (var content = new FormUrlEncodedContent(values))
using (var request = new HttpRequestMessage(HttpMethod.Post, "http://api.domain/post"){ Content = content })
using (var response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
using (var theStream = await response.Content.ReadAsStreamAsync())
using (var theStreamReader = new StreamReader(theStream))
{
string theLine = null;
while ((theLine = await theStreamReader.ReadLineAsync()) != null)
{
Console.WriteLine("----- New Line:"); //Just for the eyes
Console.WriteLine(theLine);
}
};
}
I Have an API that takes an IFormFile and returns an IActionsresult with some values. When i call the API with postman it works fine I get a nice 200 Ok response with the data I am looking for. But when I trie to call the API from within another program I get nothing in response. I get no errors, it's just that the program seems to wait for a response that never shows. I am simply wondering if anyone can see the problem with this code any help would be greately apriciated.
Both my API and my program is on the same computer and here is the code i use to call the API.
public static async Task<string> Calculate()
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var content = new MultipartFormDataContent())
{
var img = Image.FromFile("path");
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.jpeg);
content.Add(new StreamContent(new MemoryStream(ms.ToArray())), "image", "myImage.jpg");
using (var response = await client.PostAsync($"http://localhost:####/api/1.0/###", content))
{
var responseAsString = await response.Content.ReadAsStringAsync();
return responseAsString;
}
}
}
}
Successful request using postman:
Post Request using Postman
Try this-
using (var client = new HttpClient())
{
client.BaseAddress = new Uri($"http://localhost/###");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var content = new MultipartFormDataContent())
{
content.Add(new StreamContent(new MemoryStream(image)), "image", "myImage.jpg");
using (var response = await client.PostAsync($"http://localhost:#####/###/###/###", content).ConfigureAwait(false))
{
if (response.StatusCode == HttpStatusCode.OK)
{
var responseAsString = response.Content.ReadAsStringAsync().Result;
var receiptFromApi = JsonConvert.DeserializeObject<Receipt>(responseAsString);
var metadata = new metadata(bilaga)
{
Value1 = fromApi.Value1.Value,
Value2 = fromApi.Value2.Value,
Value3 = fromApi.Value3.Value,
Value4 = fromApi.Value4.Value
};
return metadata;
}
else
{
throw new InvalidProgramException();
}
}
}
}
reference- https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
I have a bot running on http://localhost:3978/api/messages.
Instead of debugging it using an emulator, can I go about using a http post request to the messaging endpoint of the bot?
If so, how do I go about doing it?
I am using c# microsoft bot framework, and I am new to this application.
I do not want to use any channels or DirectLine api, just using Httpclient.
You can do this with C# using code similar to below. Note that you would have to construct an Activity to send by setting the appropriate properties for your needs, which is not included in this code.
//make a call to get an auth token
string token;
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["grant_type"] = "client_credentials";
values["client_id"] = "YOUR APP ID";
values["client_secret"] = "NcOXRwb51joibEfzUuNE04u";
values["scope"] = "YOUR APP ID/.default";
var response =
client.UploadValues("https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token", values);
var responseString = Encoding.Default.GetString(response);
var result = JsonConvert.DeserializeObject<ResponseObject>(responseString);
token = result.access_token;
}
//you will need to adjust this value for your project.
//this example for a proxy project so the service url here is
//just an arbitrary endpoint I was using to send activities to
activity.ServiceUrl = "http://localhost:4643/api/return";
var jsonActivityAltered = JsonConvert.SerializeObject(activity);
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Authorization", $"Bearer {token}");
try
{
var btmResponse = client.UploadString("http://localhost:3971/api/messages", jsonActivityAltered);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
Have you tried using something like postman? (it's free and easy to use)
https://www.getpostman.com/
You can also write scripts in postman
otherwise you can just go to the endpoint of your API in the browser
http://localhost:3978/api/
I see you mentioned you wanted to make a console application.
You could do that. I'd suggest using postman though.
Here is an example of sending a file as well as some querystring data and Authentication using a Bearer token.
Sorry it may not be exact. Had to do a bit of copy pasting/deleting from some code examples if have
using (HttpClient client = new HttpClient())
{
JObject jsonModel = new JObject();
client.BaseAddress = new Uri("http://localhost:3978/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken);
using (var multipartFormDataContent = new MultipartFormDataContent())
{
var values = new[]
{
new KeyValuePair<string, string>("firstname", lastname),
new KeyValuePair<string, string>("lastname", lastname),
new KeyValuePair<string, string>("payloadFile", FileName)
};
foreach (var keyValuePair in values)
{
multipartFormDataContent.Add(new StringContent(keyValuePair.Value),
String.Format("\"{0}\"", keyValuePair.Key));
}
ByteArrayContent fileContent = new ByteArrayContent(File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/uploads/output/" + FileName)));
string FullxmlString = File.ReadAllText(Path.Combine(HttpContext.Current.Server.MapPath("~/uploads/output/" + FileName)));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("payloadFile") { FileName = "payloadFile" };
multipartFormDataContent.Add(fileContent);
HttpResponseMessage response = client.PostAsync("api/message", multipartFormDataContent).Result;
string returnString = response.Content.ToString();
using (HttpContent content = response.Content)
{
string res = "";
Task<string> result = content.ReadAsStringAsync();
res = result.Result;
}
}
}
I got a little question: I would like to stream an large array from my web API to my client. But I got a System.OutOfMemory Exception or an AggregateException.
My Api looks like this:
public List<MyLittlePony> Get()
{ return GetLittlePonys();}
And my Client looks like:
public string GetRequest(string URL)
{
using (var client = new System.Net.Http.HttpClient())
{
// HTTP POST
client.BaseAddress = new Uri(URL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.GetAsync("").Result;
string res = "";
using (HttpContent content = response.Content)
{
// ... Read the string.
Task<string> result = content.ReadAsStringAsync();
return result.Result;
}
}
If I'm dealing with a small size of Objects, everything works fine.
But the large one does not work.
I don't want to work with creating files or things like this.
I solved it by using this (Web API):
public HttpResponseMessage Get()
{
var result = GetLittlePonys();
var response = Request.CreateResponse();
response.Content =
new PushStreamContent((stream, content, context) =>
{
var serializer = new JsonSerializer();
using (var writer = new StreamWriter(stream))
{
serializer.Serialize(writer, result);
stream.Flush();
}
});
return response;
}
But now I have the Problem that it takes over 1 minute to transfer about 60000 elements. And this is too long for my client. Can Someone help?
I have no idea how to POST JSON with HttpClient. I find some solution, like this, but I have to use HttpClient, cause of async and have to add a header.
This is my code below. Any idea how to fix it?
List<Order> list = new List<Order> { new Order() { Name = "CreatedTime", OrderBy = 1 } };
Queues items = new Queues { Orders = list };
var values = new Dictionary<string, string> { { "Orders", JsonConvert.SerializeObject(list) } };
var content = new FormUrlEncodedContent(values);
//HttpContent cc = new StringContent(JsonConvert.SerializeObject(items));
_msg = await _client.PostAsync(input, content);
//_msg = await _client.PostAsync(input, cc);
var response = await _msg.Content.ReadAsStringAsync();
You can use the method PostAsJsonAsync which can be found in the extensions assemblies:
System.Net.Http.Formatting.dll
Example
public static async Task SendJsonDemo(object content)
{
using(var client = new HttpClient())
{
var response = await client.PostAsJsonAsync("https://example.com", content);
}
}
If you want to add custom headers to the request, add it to DefaultRequestHeaders:
client.DefaultRequestHeaders.Add("mycustom", "header1");
You can send any type of request like as
public static async Task<HttpResponseMessage> SendRequest(HttpMethod method, string endPoint, string accessToken, dynamic content = null)
{
HttpResponseMessage response = null;
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(method, endPoint))
{
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
if (content != null)
{
string c;
if (content is string)
c = content;
else
c = JsonConvert.SerializeObject(content);
request.Content = new StringContent(c, Encoding.UTF8, "application/json");
}
response = await client.SendAsync(request).ConfigureAwait(false);
}
}
return response;
}