How to add "application/x-www-form-urlencoded" as Content-type in .Net httpClient - asp.net

I cannot add Content-type as "application/x-www-form-urlencoded". There is throwing an error. Only for the this content-type. Thank You for the attention.
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = new HttpMethod("POST"),
RequestUri = new Uri(path),
};
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
HttpResponseMessage response1 = await httpClient.SendAsync(request);
var token = await response1.Content.ReadAsStringAsync();
}
It's throwing error like that
"Misused header name, 'Content-Type'. Make sure request headers are
used with HttpRequestMessage, response headers with
HttpResponseMessage, and content headers with HttpContent objects."

The content type is a header of the content, not of the request, which is why this is failing.
One way is that you can call TryAddWithoutValidation instead of add like below:
request.Headers.TryAddWithoutValidation("Accept", "application/json");
request.Headers.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded");
The other way is that you can set the Content-Type when creating the request content itself, refer to this answer.

I'v used something more complicated but it works.
var client = new HttpClient();
//headers dictionary
var dict = new Dictionary<string, string>();
dict.Add("Content-Type", "application/x-www-form-urlencoded");
//request
var req = new HttpRequestMessage(HttpMethod.Post, new Uri(url)) { Content = new FormUrlEncodedContent(dict) };
req.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencode"));
var response = await client.SendAsync(req);

Related

WebApi Specify Content-Type as application/json

I'm trying to return a JSON object retrieved from a 3rd party API.
[Route("api/Catalog/Categories")]
public class CategoriesController : Controller
{
//Get all categories
[HttpGet]
public IActionResult Get()
{
var client = new RestClient();
client.BaseUrl = new Uri("http://api.tcgplayer.com");
var request = new RestRequest(Method.GET);
request.Resource = "/catalog/categories";
request.RequestFormat = DataFormat.Json;
request.AddHeader("Content-Type", "application/json; charset=utf-8");
request.AddHeader("Authorization", "Bearer redacted");
var tcgResponse = client.Execute(request);
return Ok(tcgResponse.Content);
}
}
The content type shows as "document", which is not desirable. How do specify the content type as "application/json"?
I have already tried adding
[Produces("application/json")]
but this caused double serialization of my response content.
FTR I ended up deserializing and reserializing for the return statement. Not pretty, but it works.
var tcgResponse = client.Execute(request);
var r = JsonConvert.DeserializeObject<dynamic>(tcgResponse.Content);
return r;

Delete function IRestResponse with RestSharp

I want to implement a delete function with a Restful API with RestSharp. I have implemended GET and POST function already. But with this delete function I don't get any feedback from the API only a httpresponse. My question is how do I make my code so I can excecute the delete function? I already have this:
// var url = string.Format("url");
// Construct the request.
// var request = new RestRequest(url, Method.DELETE);
// //IRestResponse<> response;
// //response = await restClient.ExecuteTaskAsync<>(request);
// //return response.Data;
try it
var client = new RestClient(url);
var request = new RestRequest(Method.DELETE);
IRestResponse response = client.Execute(request);
The important point here is to include "Accept" in header with value shown in code.
string url = "http://localhost:8080/laptop-bag/webapi/api/delete/2";
IRestRequest restRequest = new RestRequest(url);
restRequest.AddHeader("Accept", "*/*"); //Important
IRestClient restClient = new RestClient();
IRestResponse restResponse = restClient.Delete(restRequest);
//Status code will be 200 for successful execution
int statusCode = Convert.ToInt32(restResponse.StatusCode);

HttpClient.SendAsync() is not sending JSON as string

I'm having trouble figuring out what's wrong with HttpClient script.
When I use Fiddler, it works & AspNetCore MVC isn't throwing errors.
http://localhost:6004/api/XUnitExamplesTest/JsonStringMethod
Http-Get
User-Agent: Fiddler
Accept: text/json
Content-Type: text/json
Host: localhost:6004
Content-Length: 24
"{\"Color\": \"Green\"}"
But HttpClient script causing AspNetCore MVC issues.
var sampleData = new XUnitSampleData() { Color = "Red" };
var contentType = "text/json";
var httpMethod = HttpMethod.Get;
var uriPath = "JsonStringMethod";
var jsonData = JsonConvert.SerializeObject(_sampleData, Formatting.None).ToString(); // JSON String. --> "{ \"Vin\" : \"foo\", \"Color\" : \"foo\" }"
var jsonRequest = string.Format("\"{0}\"", jsonData);
var result = await XUnitWebClient.GetAsync3(contentType, httpMethod, uriPath, jsonRequest, CancellationToken.None);
public static async Task<string> GetAsync3(string contentType, HttpMethod httpMethod, string uriPath, string request, CancellationToken cancellationToken)
{
using (var httpClient = new HttpClient())
{
using (var httpRequestMessage = new HttpRequestMessage(httpMethod, string.Format("{0}{1}", _uri, uriPath)))
{
httpClient.BaseAddress = new Uri(string.Format("{0}", _baseAddress));
//httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType)); // "Accept" Header.
//httpClient.DefaultRequestHeaders.Remove("Content-Type");
//httpClient.DefaultRequestHeaders.Add("Content-Type", contentType);
httpRequestMessage.Content = new StringContent(request, Encoding.UTF8, contentType); // "Content-Type" Header.
var response = await httpClient.SendAsync(httpRequestMessage);
return await response.Content.ReadAsStringAsync();
}
}
}
AspNetCore MVC got the JSON value as "{".
Since I'm using text/json so how do I tell HttpClient to send json string with beginning quote and ending quote, instead of it stripping that out?
Or am I doing something wrong with JsonConvert.SerializeObject() here?
To answer the question directly...
You're not escaping the quotes inside the JSON string. Try this:
var jsonRequest = string.Format("\"{0}\"", jsonData.Replace("\"", "\\\""));
However...
I question how you're approaching this problem. You mention in your comments that you get an error on the server side (in your MVC code) if you don't stringify the JSON on the client side. However, it is very awkward and non-standard to require the client to do this. I would:
Change the content type from text/json to application/json. That won't fix the problem, but it is the standard.
Remove the line above and send jsonData directly. i.e. don't stringify the JSON.
Ask a new question about how to solve the server-side error you're getting, and post the relevant MVC code.

How to post to external resource from WebApi?

WebApi controller has to post model to a separate Api. Is this possible and if so, how?
Yes, this is possible using the HttpClient class.
Here's an example:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://example.com");
var content = new StringContent("{\"foo\":\"bar\"}", Encoding.UTF8, "application/json");
await client.PostAsync("/api", content);
}
And if you already have a model you could JSON serialize it before passing:
string json = JsonConvert.SerializeObject(model);
var content = new StringContent(json, Encoding.UTF8, "application/json");
There's also the PostAsJsonAsync extension method which could be used to simplify the code:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://example.com");
await client.PostAsJsonAsync("/api", model);
}

REST WEBAPI POST method with parameters not being called

I have built a REST API with a controller having a POST method with 4 parameters like this-
[HttpPost]
public void SaveSession([FromBody] string userId, [FromBody] DateTime issueDateTime, [FromBody] string browserType, [FromBody] string salt)
{
// Params need to be changed
_sessionService.SaveSession(userId, issueDateTime, browserType, salt);
}
How should I POST data on the client side, I mean what should be the format of the data to be sent?
I tried this format-
"userId=abc&DateTime=someDatetime&browserType=somebrowser&salt=somesalt"
Its not working if I try this, The web service method is not even being called
Could anyone tell me the correct format?
EDIT:
Here is how I am calling the API-
const string endPoint = #"http://localhost:85/session/Test";
var postData = "userId=abc&DateTime=someDatetime&browserType=somebrowser&salt=somesalt"
var request = (HttpWebRequest) WebRequest.Create(EndPoint + parameters);
request.Method = "POST";
request.ContentLength = 0;
request.ContentType = "application/x-www-form-urlencoded";
if (!string.IsNullOrEmpty(postData) && Method == HttpVerb.POST)
{
var encoding = new UTF8Encoding();
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(postData);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
}
using (var response = (HttpWebResponse) request.GetResponse())
{
var xmlDoc = new XmlDocument();
if (response.StatusCode != HttpStatusCode.OK)
{
var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException(message);
}
// grab the response
var responseStream = response.GetResponseStream();
if (responseStream != null)
{
xmlDoc.Load(responseStream);
}
return (xmlDoc);
}
Thanks!
I assume routing has been properly configured.
Said so.... DateTime parameter in the controller method has been named "issueDateTime" while within the request has been named "DateTime".
I got to know, what mistake I was doing. I was sending 4 parameters in a WebService method. We can only send one parameter while calling a web service method. If you want to send multiple data, just send it as an object. Like this -
[HttpPost]
public void SaveSession([FromBody] Values value)
{
var userId = values.userId,
var issueDateTime= values.issueDateTime,
var browserType= values.browserType,
var salt= values.salt,
_sessionService.SaveSession(userId, issueDateTime, browserType, salt);
}

Resources