Here follows a simple action method of one of my controllers:
[HttpPost]
public async Task<dynamic> UnitTest()
{
var httpClient = new HttpClient();
dynamic model1 = new ExpandoObject();
model1.title = "foo";
model1.body = "bar";
model1.userId = 1;
var request = JsonConvert.SerializeObject(model1);
var url = "https://jsonplaceholder.typicode.com/posts";
var response = await httpClient.PostAsync(url,
new StringContent(request, Encoding.UTF8, "application/json"));
return response;
}
I would expect response to include an object like
{
id: 101,
title: 'foo',
body: 'bar',
userId: 1
}
According to https://github.com/typicode/jsonplaceholder#how-to. Instead, response is an object with the following properties:
Content (empty)
StatusCode: 201
ReasonPhrase: "Created"
Version: 1.1
What am I doing wrong?
response.Content is stream content and you should read the stream first before return action.
var content = await response.Content.ReadAsStringAsync();
Complete action looks like;
[HttpPost]
public async Task<string> UnitTest()
{
var httpClient = new HttpClient();
dynamic model1 = new ExpandoObject();
model1.title = "foo";
model1.body = "bar";
model1.userId = 1;
var request = JsonConvert.SerializeObject(model1);
var url = "https://jsonplaceholder.typicode.com/posts";
var response = await httpClient.PostAsync(url,
new StringContent(request, Encoding.UTF8, "application/json"));
var content = await response.Content.ReadAsStringAsync();
return content;
}
Also, it could be better to deserialize returned json as known type.
You just need to read the content then deserialize it to object before passing back.
var str = await response.Content.ReadAsStringAsync();
var obj = JsonConvert.DeserializeObject(str);
return obj;
Related
Trying to update my JSON file, I get the return code 'OK' (200), but the file doesn't change. The JSON string contains the updated entry.
What do I wrong?
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Accept", "application/json;charset=UTF-8");
RootObject root = null;
HttpResponseMessage HttpResponseMessage = await httpClient.GetAsync("http://localhost/fruits.json",
HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
if (HttpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK)
{
HttpContent HttpContent = HttpResponseMessage.Content;
string MyContent = await HttpContent.ReadAsStringAsync();
root = JsonConvert.DeserializeObject<RootObject>(MyContent);
ReturnContentModels = new AsyncObservableCollection<ContentModel>(root.products);
Debugger.Break();
}
ContentModel contentModel = ReturnContentModels[0];
contentModel.Name = "Apfelsinen";
List<ContentModel> products1 = new List<ContentModel>(ReturnContentModels);
RootObject root1 = new RootObject
{
meta = root.meta,
products = products1
};
string json = JsonConvert.SerializeObject(root1, Formatting.Indented);
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("http://localhost/fruits.json", stringContent);
Debugger.Break();
What I understand is that you are currently getting the record from a JSON file directly and modifying it. You cannot directly modify a file using httpClient. You need a server (back-end application) of some kind to understand your POST request.
You can use JSON-Server to serve your JSONfile and make GET, POST and other requests to it.
I'm trying to send a http post request in JSON format which should look like this:
{
"id":"72832",
"name":"John"
}
I have attempted to do it like below but if I am correct this is not sending a request in json format.
var values = new Dictionary<string,string>
{
{"id","72832"},
{"name","John"}
};
using (HttpClient client = new HttpClient())
{
var content = new FormUrlEncodedContent(values);
HttpResponseMessage response = await client.PostAsync("https://myurl",content);
// code to do something with response
}
How could I modify the code to send the request in json format?
try this
using (var client = new HttpClient())
{
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
var baseAddress = "https://....";
var api = "/controller/action";
client.BaseAddress = new Uri(baseAddress);
client.DefaultRequestHeaders.Accept.Add(contentType);
var data = new Dictionary<string,string>
{
{"id","72832"},
{"name","John"}
};
var jsonData = JsonConvert.SerializeObject(data);
var contentData = new StringContent(jsonData, Encoding.UTF8, "application/json");
var response = await client.PostAsync(api, contentData);
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<object>(stringData);
}
}
Update
If the request comes back with Json data in the form `
{ "return":"8.00", "name":"John" }
you have to create result model
public class ResultModel
{
public string Name {get; set;}
public double Return {get; set;}
}
and code will be
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<ResultModel>(stringData);
var value=result.Return;
var name=Result.Name;
}
I would start off by using RestSharp.
dotnet add package RestSharp
Then you can send requests like this:
public async Task<IRestResult> PostAsync(string url, object body)
{
var client = new RestClient(url);
client.Timeout = -1;
var request = new RestRequest(Method.Post);
request.AddJsonBody(body);
var response = await client.ExecuteAsync(request);
return response;
}
Just pass in your dictionary as the body object - I would recommend creating a DTOS class to send through though.
Then you can get certain aspects of the RestResponse object that is returned like:
var returnContent = response.Content;
var statusCode = response.StatusCode;
I have an endpoint in my ASP.NET Core 2.1 Controller
[HttpPost]
public async Task<bool> CheckStatus([FromBody] StatusModel model)
{
...code ommited
return true;
}
And I call this endpoint from other place in code like this:
await client.PostAsync('/CheckStatus', payloayd)
How can I retrive a bool value from this request?
Using Newtonsoft.Json, you can read the response of the request and parse it into a bool.
using Newtonsoft.Json;
public async Task<bool> GetBooleanAsync()
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var data = new { };
var url = "my site url";
var payload = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
var req = await client.PostAsync(url, payload);
var response = await req.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<bool>(response);
}
}
UPDATE
Looking back on this from a few years on, this can be simplified without the use of Newtonsoft.Json to read the response, by simply parsing the string data to a boolean.
public async Task<bool> GetBooleanAsync()
{
var data = new { };
var url = "my site url";
var payload = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
using var client = new HttpClient();
var response = await client.PostAsync(url, payload);
var data = await response.Content.ReadAsStringAsync();
return boolean.Parse(data);
}
However, if your boolean value is returned in a JSON object, then Newtonsoft.Json could be used to read that value.
This is my MVC Controllers code.
[HttpPost]
public async Task<IActionResult> InsertNewStudentAsync(ViewModel.StudentPersonalDetailsViewModel ob)
{
StudentModel obj = ViewModel.StudentPersonalDetailsViewModel.Translate(ob);
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:52494/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var bodyData = ViewModel.StudentPersonalDetailsViewModel.Translate(ob);
//HttpContent ob = new HttpContent();
var response = await client.PostAsync("api/Student/InsertStudent",obj);
}
return View();
}
In the line var response = await client.PostAsync("api/Student/InsertStudent",obj);
It is showing me an error on obj showing that
Error CS1503 Argument 2: cannot convert from 'SMS.Domain.Models.StudentModel' to 'System.Net.Http.HttpContent'
How do I pass that object to my API's controller.
That is because it is expecting a HttpContent derived class.
Either use the PostAsJsonAsync extension method
var response = await client.PostAsJsonAsync("api/Student/InsertStudent",obj);
or convert it yourself
var json = JsonConvert.SerializeObject(obj);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("api/Student/InsertStudent", content);
Which is basically what the extension method is doing under the hood.
Here is an example of rolling your own extension method if you do not want to add additional dependencies.
public static Task<HttpResponseMessage> PostAsJsonAsync<T>(this HttpClient client, string requestUri, T obj) {
var json = JsonConvert.SerializeObject(obj);
var content = new StringContent(json, Encoding.UTF8, "application/json");
return client.PostAsync(requestUri, content);
}
I have an object.
I'am sending it this to my api project this way :
mymodel obj = new mymodel();
obj.prop = "this";
obj.prop2 = "prop2";
var content = JsonConvert.SerializeObject(obj);
var buffer = System.Text.Encoding.UTF8.GetBytes(content);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
string response = "";
using (HttpClient client = new HttpClient())
{
var rez = await client.PostAsync(uri + myenum.Insert, byteContent).ConfigureAwait(false);
response = rez.ToString();
}
In my api method i want to convert that string or http content again to model.
[ActionName("Insert")]
[HttpGet]
public bool Insert(string obj)
{
try
{
mymodel model = JsonConvert.DeserializeObject<mymodel>(obj);
How to handle object i'am sending with postasync in my api method ?
Any help ?
First you cannot use PostAsync on a HTTPGet method.
Second, I dont understand what you mean. If you are using json then you dont have to do anything. Just have a simple client method as such:
public async Task<TResult> PostAsync<TResult, TInput>(string uriString, TInput payload = null) where TInput : class
{
var uri = new Uri(uriString);
using (var client = GetHttpClient())
{
var jsonContent = JsonConvert.SerializeObject(payload, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
HttpResponseMessage response = await client.PostAsync(uri, new StringContent(jsonContent, Encoding.UTF8, "application/json"));
if (response.StatusCode != HttpStatusCode.OK)
{
//Log.Error(response.ReasonPhrase);
return default(TResult);
}
var json = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<TResult>(json);
}
}
And you can just add the same object to your API like
[ActionName("Insert")]
[HttpPost]
public bool Insert(YourObjectClass obj)
{
try
{
....code....
}
}