Invalid operation during the http request - c#

I'm writing a windows forms app where user have to enter email address and I need to check if it's valid.
I have found Mashape API but I get an exception;
"An unhandled exception of type 'System.InvalidOperationException' occurred in System.Net.Http.dll" error in Unirest library.
Error occurs in line with msg.Headers.Add(header.Key, header.Value);
Values are:
header.Key = "Content-type"
header.Value = "application/json"
Debugger says:
"Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects."
I can't find any solution, does anyone has any idea how to fix it?
Task<HttpResponse<EWSemail>> response = Unirest.post("https://email.p.mashape.com/")
.header("X-Mashape-Key", myKey)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.body("{\"email\":\"" + tbEmail.Text + "\"}")
.asJsonAsync<EWSemail>();
Unirest library:
private static Task<HttpResponseMessage> RequestHelper(HttpRequest request)
{
if (!request.Headers.ContainsKey("user-agent"))
{
request.Headers.Add("user-agent", USER_AGENT);
}
var client = new HttpClient();
var msg = new HttpRequestMessage(request.HttpMethod, request.URL);
foreach (var header in request.Headers)
{
msg.Headers.Add(header.Key, header.Value);
} // ^^"Content-Type" ^^ "application/json"
if (request.Body.Any())
{
msg.Content = request.Body;
}
return client.SendAsync(msg);
}

The error message says:
"Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects."
Content-Type, as the name would imply, is a content header. Therefore, set it on msg.Content.Headers, not msg.Headers.
If I remember correctly, you can set it directly via msg.Content.Headers.ContentType = new MediaHeaderTypeValue("application/json");

OK, it doesn't work because syntax that Mashape provide is bad. In this case header.Key has to be "ContentType" (Reference: https://msdn.microsoft.com/en-us/library/system.net.httprequestheader%28v=vs.110%29.aspx).
I'm sorry for my rubbish post and thank you #codran, your answer helped me to find this answer.

Related

Sending custom Content-Type using HttpClient C# .Net6

Hello Stackoverflow community. I hope someone here can help me!!
I'm trying to integrate with the Zoopla API that requires the post request to send the following customized content type. (I've got the certificate side of things working fine).
application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json
I've tried the following approaches without any success (they all result in the following error)
System.FormatException: 'The format of value 'application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json' is invalid.'
Initial approach was to set it within the content of the RequestMessage
var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list"),
Method = HttpMethod.Post,
Content = new StringContent(jsonBody, Encoding.UTF8, "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json")
};
When that didn't work I tried to set it via the default headers (the client below is from the ClientFactory)
client.DefaultRequestHeaders.Add("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
My final attempt was to set it without validation
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
I've just tried something else which unfortunately didn't work
string header = "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json";
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(header));
I am well and truly stumped!! HELP!! :-)
Content-Type is set on the content, not in DefaultRequestHeaders. You may try using TryAddWithoutValidation on the request content:
var content = new StringContent("hello");
content.Headers.ContentType = null; // zero out default content type
content.Headers.TryAddWithoutValidation("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
var client = new HttpClient(); // note: use IHttpClientFactory in non-example code
var response = await client.PostAsync("https://postman-echo.com/post", content);
Console.WriteLine(response.StatusCode); // OK
Console.WriteLine(await response.Content.ReadAsStringAsync());
// {"args":{},"data":{},"files":{},"form":{},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-6345b568-22cc353761f361483f2c3157","content-length":"5","content-type":"application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json"},"json":null,"url":"https://postman-echo.com/post"}

How can I set response header in httpclient in C#?

I am getting response in text/html format.How can I set response header so that I get response in application/json format.
Code:
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = builder.Uri,
Headers = {
{ HttpResponseHeader.ContentType.ToString(), "application/json" },
{ "Auth", "###################################################" }
}
};
var httpResponse = await _httpClient.SendAsync(httpRequestMessage);
You don't. Content-Type header
In responses, a Content-Type header tells the client what the content type of the returned content actually is.
The server decides the content type of the response and the client uses it to handle accordingly. There is nothing you can set in your request to do that out of the box.
If you are handling the response creation, you could create a custom header to indicate the type of the response and have the server side code handle it, but that's not usually how it should be done.
As stated by #Athanasios, you cannot specify the Content-Type returned by the server. But, there is one thing you can try : you can tell the server that you'd like to get a JSON format response.
Set the HTTP Header Accept to application/json
But, it's still up to the server in the end to decide what content will be returned
It seems that you are looking for Accept header. Try next:
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = builder.Uri,
Headers = {
{ "Accept", "application/json"},
{ "Auth", "###################################################" }
}
};

How to return JSON response object

I am getting this error even though I added media formatter as follows. I am testing with postman. Postman headers content-type is application/json and body is x-www-form-urlencoded. How can I fix it?
"ExceptionMessage": "No MediaTypeFormatter is available to read an
object of type 'Initiate' from content with media type 'text/html'.",
"ExceptionType": "System.Net.Http.UnsupportedMediaTypeException"
Here is my code sample:
[RoutePrefix("api/v1/pin")]
public class GameController : ApiController
{
// POST: api/Game
[HttpPost, Route("initiation")]
public async System.Threading.Tasks.Task<Initiate> PurchaseInitiationAsync([FromBody]Initiate value)
{
if (value == null)
{
var message = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent(string.Format("Request is NULL! Please check your data.")),
ReasonPhrase = "Request is NULL! Please check your data."
};
throw new HttpResponseException(message);
}
HttpClient httpClient = new HttpClient();
HttpContent content = new StringContent(
JsonConvert.SerializeObject(value),
Encoding.UTF8,
"application/json"
);
HttpResponseMessage response =
await httpClient.PostAsync("http://test:1907/purchase_initiation", content);
var obj = response.Content.ReadAsAsync<Initiate>(
new List<MediaTypeFormatter>
{
new JsonMediaTypeFormatter()
}).Result;
return obj;
}
}
I can only reproduce this if the request content type hitting api/v1/pin/initiation is text/html. You say that your Postman settings are set to application/json and body is x-www-form-urlencoded, but from my testing if that was the case the exception you've shown above wouldn't be thrown.
I would double check that Postman is actually sending the correct content type header by opening the Postman console (CTRL+ALT+C) and inspecting the request headers.

Adding Comment to Fortify Issue via REST API results in Content Encoding Error

I'm trying to add a comment to an issue inside Fortify. When I POST what I think is the correct JSON, I receive the response "{"message":"Content was incorrectly formatted (expected application/json; charset=utf-8).","responseCode":400,"errorCode":-20209}"
However, if I use Fiddler to examine the message I'm POSTing and receiving the appropriate headers appear to be in place. What secondary issue could be causing this exception to be thrown?
Fortify v18.10.0187
.NET v4.6.2
Newtonsoft.Json v9.0.0
public static string PostCommentIssue(FortifyComment fc)
{
var content = JsonConvert.SerializeObject(fc);
var postUri = String.Format(Configuration.FortifyCommentsUri, fc.data.issueId);
return WebServiceHelper.PostMessage(postUri, content);
}
public static string PostMessage(string url, string content)
{
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
requestMessage.Headers.Add("Authorization", Configuration.FortifyAuthorization.ToHeader());
requestMessage.Content = new StringContent(content, Encoding.UTF8, JsonMediaTypeFormatter.DefaultMediaType.MediaType);
HttpResponseMessage hrm = HttpClient.SendAsync(requestMessage).Result;
hrm.EnsureSuccessStatusCode();
HttpContent hc = hrm.Content;
return hc.ReadAsStringAsync().Result;
}
FortifyComment is just an object with the basic elements of a comment in it. It's based on the Fortify response given on a query (thus the inner data element).
Using
FortifyComment fc = new FortifyComment();
fc.data.issueId = defect.id;
fc.data.comment = String.Format("TFS #{0}.", tfsNumber);
FortifyHelper.PostCommentIssue(fc);
I receive the 400 error. Screenshot of Fiddler intercept:

C#: Sending parameter with Content-Type Header in HTTP

I am trying to send the HTTP post request using HTTP client.while setting my Content-Type header with StringContent method, I am getting the error:
the format "application/json;ty=2 "is incorrect
My code is as follows:
string result2 = JsonConvert.SerializeObject(values);
var content = new StringContent(result2, Encoding.UTF8, "application/json; ty=2");
var response = await client.PostAsync("http://127.0.0.1:8080/~/in-cse/in-name", content);
var response_string = await response.Content.ReadAsStringAsync();
But in my HTTP Post format I have to include ty=2 parameter along with application/json. I have tested this with Postmanand it worked perfectly. How can I achieve the same thing here. I also even found you can add parameter to content type in the following format:
content := "Content-Type" ":" type "/" subtype *(";" parameter)
then why is it not working for me.
**EDIT:**even tried this:
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:8080/~/in-cse/in-name");
request.Content = new StringContent(result2, Encoding.UTF8, "application/json;ty=2");
client.SendAsync(request).ContinueWith(resposetask => { Console.WriteLine("response:{0}", resposetask.Result); });
same error i am getting
You will have to use TryAddWithoutValidation in DefaultRequestHeaders in HttpClient like following:
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json;ty=2");

Categories

Resources