What's wrong with the API call request - api

Working on a third part API host. The API call requires a few key/value pairs in the request body with the following example fields:
field1: fieldValue1
field2: fieldValue2
field3: fieldValue3
field4: fieldValue4
The content type should be "application/x-www-form-urlencoded".
When using Postman to make the call, it's always successful. However, when changed to use a simple service to make the call, it's failing. The following is the piece of code that set up the HttpRequestMesage and make the call:
HttpResponseMessage response;
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://soem.thirdpartyAPIHost.net"))
{
request.Content = new StringContent("{\"field1\":\"fieldValue1\",\"field2\":\"fieldValue2\",\"field3\":\"fieldValue3\",\"field4\":\"fieldValue4\"}", Encoding.UTF8, "application/x-www-form-urlencoded");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
response = await httpClient.SendAsync(request);
}
}
What's wrong with this implementation?

Found the issue: the content type is Url encoded and therefore the string cannot be in Json format. Instead, the content key/value pairs should be chained together using '&', just like when the parameters are embedded in the Url. So, the sample content in the question should be like this:
request.Content = new StringContent("field1=fieldValue1&field2=fieldValue2&field3=fieldValue3&field4=fieldValue4", Encoding.UTF8, "application/x-www-form-urlencoded");
Please also reference the following: How to send a POST request with Content-Type "application/x-www-form-urlencoded"

Related

net Core 3.1 Object null in WebApi method after PostAsJsonAsync

Im using this line to consume the API post method
var postTask = client.PostAsJsonAsync("AgregarNegocio", new StringContent(JsonConvert.SerializeObject(model).ToString(), Encoding.UTF8, "application/json"));
however when the API method is hit
public IActionResult AgregarNegocio([FromBody]NegocioViewModel model)
all the properties in model are null...
i already tried with and without [FromBody] and other solutions but none has worked yet, any suggestions?, thanks!
You need to construct your http client like this:
_client = new HttpClient { BaseAddress = new Uri("your http://my base url goes here"),
Timeout = new TimeSpan(0, 0, 0, 0, -1) };
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));//add json header
//_client.DefaultRequestHeaders.Add("Bearer", "some token goes here");
and you need to call your method like this:
var postTask = await _client.PostAsJsonAsync("AgregarNegocio", model);
make sure you call "await" on it because it is async.
NOTES:
Notice that I added MediaTypeWithQualityHeaderValue to indicate that it is json.
Also using Route usually is not a good idea... It is better to use HttPost("MyRoute") because it combined the ControllerName + Route. But it is up to you.
Try to use PostAsync instead of PostAsJsonAsync
var postTask = await client.PostAsync("AgregarNegocio", new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json"));
You can use the HttpClient extension method :
https://learn.microsoft.com/en-us/previous-versions/aspnet/hh944682(v=vs.118)
PostAsJsonAsync(
this HttpClient client,
string requestUri,
T value
)
var postTask = client.PostAsJsonAsync<NegocioViewModel>("AgregarNegocio", model);
You can use PostAsync but also do not forget about using HttpClient in right way as i described in this article.

How to get string from httpclient request

I tried to get twitch api information but request dosent show anything
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.twitch.tv/helix/streams?game_id=33214"))
{
request.Headers.TryAddWithoutValidation("Client-ID", "ozzdg2w66nugbxdhrzzy5d7z");
var response = await httpClient.SendAsync(request);
}
}
I would use api request to get output precise number, but twitch channel names are not working anymore and you need channel ID which are private.
Basically what I need are 3 things:
Is channel live (true/false)
Live viewership count
thumbnail picture
Is there a way get those data? Or I need to know the secret ID?
I didn't get the conection between your topic and the description of your problem.
But if you want to request stream information you have to use the right endpoint url.
Like: https://api.twitch.tv/helix/streams?user_login=USER_NAME
For more information read the reference documentation https://dev.twitch.tv/docs/api/reference/#get-streams

WCF responds with HTTP 400 to serialized JSON string from Razor Pages app

I'm trying to POST a request containing JSON from a Razor Pages app to a WCF service endpoint expecting a Json WebMessageFormat and Bare BodyStyle.The JSON passes just fine via Postman, but not when I send it through http-client. Wireshark also shows some extra bytes around JSON in the http-client produced packet that are not present in the Postman packet. Wireshark also reports this as line-based text data: application/json for the Postman packet. The .Net packet is JavaScript Object Notation: application/json.
Here's my C# code to send the JSON to the WCF endpoint:
var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:8000");
dynamic foo = new ExpandoObject();
foo.position = 1;
var content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(foo), System.Text.Encoding.UTF8, "application/json");
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:8000/WCFService/ControllerV1/PostJSON");
request.Headers.Add("cache-control", "no-cache");
request.Headers.Add("Accept", "*/*");
request.Headers.Add("Connection", "keep-alive");
request.Content = content;
try
{
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException e)
{
Console.WriteLine(e.Message);
}
And here's my WCF endpoint declaration:
[OperationContract, WebInvoke(Method="POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
void PostJSON(string jsonString);
I would expect the packets to produce the same response from the server, but, what appears to be the same string produces a response 200 when the packet is built by postman and a response 400 when built by .Net. I'm clearly missing something subtle here, but I can't seem to tease it out.
There are 2 possible BodyStyle for request and response, wrapped or bare. When you specify wrapped body style the WCF service expects a valid json to be passed which in your case would be
//note that property name is case sensitive and must match service parameter name
{
"jsonString": "some value"
}
And when you specify bare format the service expects only plain string value (in case of primitive type as yours) as the request like this
"some value"
When you serialize your object like this
dynamic foo = new ExpandoObject();
foo.position = 1;
string result = JsonConvert.SerializeObject(foo);
the result contains the following json
{
"position":1
}
which corresponds to wrapped format and the service returns 400: Bad Request. All you need to do is to turn this json into valid json string value like this
"{\"position\":1}"
It can be done by repeated JsonConvert.SerializeObject call
dynamic foo = new ExpandoObject();
foo.position = 1;
string wrapped = JsonConvert.SerializeObject(foo);
string bare = JsonConvert.SerializeObject(wrapped);
var content = new StringContent(bare, System.Text.Encoding.UTF8, "application/json");

Get string returned from a PostAsync event

I'm using HttpClient like this in my console app:
using (var http = new HttpClient(handler))
{
http.BaseAddress = new Uri("http://127.0.0.1:34323/");
var response = await http.PostAsync("/api/generate", new StringContent(
JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json"));
Console.WriteLine(response.Content.ToString());
}
In debug mode, I can see that the controller is returning a string of JSON.
However, I only get this written to the console:
System.Net.Http.StreamContent
How can I get it to write the actual JSON that's being returned?
Thanks!
Try below line:
Console.WriteLine(response.Content.ReadAsStringAsync().Result.ToString());

REST Stream's OutgoingResponse.ContentType is ignored, always shows "application/xml" on receiving browser

I have a self-hosted WCF REST/webHttpBinding-endpoint-bound service. I have a few streams of different content types that it serves. The content itself is delivered correctly, but any OutgoingResponse.ContentType setting seems to be ignored and instead delivered as "application/xml" every time.
Browsers seems to get over it for javascript and html (depending on how it's to be consumed), but not for css files which are interpreted more strictly. CSS files are how I realized the problem but it's a problem for all Streams. Chromebug and IE developer tools both show "application/xml" regardless of what I put in the serving code for a content type. I've also tried setting the content type header as a Header in OutgoingResponse but that makes no difference and it probably just a long way of doing what OutgoingResponse.ContentType does already.
[OperationBehavior]
System.IO.Stream IContentChannel.Code_js()
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/javascript;charset=utf-8";
var ms = new System.IO.MemoryStream();
using (var sw = new System.IO.StreamWriter(ms, Encoding.UTF8, 512, true))
{
sw.Write(Resources.code_js);
sw.Flush();
}
ms.Position = 0;
return ms;
}
This behavior is added:
var whb = new WebHttpBehavior
{
DefaultBodyStyle = System.ServiceModel.Web.WebMessageBodyStyle.WrappedRequest,
DefaultOutgoingRequestFormat = System.ServiceModel.Web.WebMessageFormat.Json,
DefaultOutgoingResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json,
HelpEnabled = false
};
I've tried setting AutomaticFormatSelectionEnabled = true and false just in case because it came up in google searches on this issue, but that has no effect on this.
I'm finding enough articles that show Stream and ContentType working together to confuse the heck out of me as to why this isn't working. I believe that the Stream is only intended to be the body of the response, not the entire envelope.
My .svclog doesn't show anything interesting/relevant that I recognize.
============
I can confirm in Fiddler2 that the headers are being delivered as shown in the browser.
...
Content-Type: application/xml; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
...
Solved!
I had something like the following in a MessageInspector:
HttpResponseMessageProperty responseProperty = new HttpResponseMessageProperty();
responseProperty.Headers.Add("Access-Control-Allow-Origin", "*");
reply.Properties["httpResponse"] = responseProperty;
and this was overwriting the already-present HttpResponseMessageProperty in reply.Properties, including any contentType settings. Instead, I tryget the HttpResponseMessageProperty first and use the existing one if found.
I lucked out seeing that one.