C# - Set header within HTTP POST request [duplicate] - c#

I'm trying to add a custom header to the request header of my web application. In my web application im retrieving data from a web api, in this request i want to add a custom header which contains the string sessionID. I'm looking for a general solution so that I dont have to add the same code before every call I make.
My Controller looks like this:
[HttpGet]
public async Task<ActionResult> getCall()
{
string url = "http://localhost:51080/";
string customerApi = "customer/1";
using (var client = new HttpClient())
{
//get logged in userID
HttpContext context = System.Web.HttpContext.Current;
string sessionID = context.Session["userID"].ToString();
//Create request and add headers
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//Custom header
//Response
HttpResponseMessage response = await client.GetAsync(customerApi);
if (response.IsSuccessStatusCode)
{
string jsondata = await response.Content.ReadAsStringAsync();
return Content(jsondata, "application/json");
}
return Json(1, JsonRequestBehavior.AllowGet);
}
}
Hope anybody can help!
Thanks in advance!

Try this:
client.DefaultRequestHeaders.Add("X-Version","1");

Collection behind DefaultRequestHeaders has Add method which allows you to add whatever header you need:
client.DefaultRequestHeaders.Add("headerName", sesssionID);

Related

Send a string in body via SendRequestAsync

I need to send a Patch request to a backend API via SendRequestAsync func. This is regarding a UWP C# app.
Backend expected to like this:
On the app this is the code I wrote. But doesn't work
if (requestMehtod == ApplicationConstants.RequestType.PATCH)
{
Uri uri = new Uri(requestUrl);
HttpRequestMessage requestMessage = null;
if (postData != null)
{
var itemAsJson = JsonConvert.SerializeObject(postData);
requestMessage = new HttpRequestMessage(HttpMethod.Patch, uri)
{
Content = new HttpStringContent(itemAsJson, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json-patch+json")
};
}
else
{
requestMessage = new HttpRequestMessage(HttpMethod.Patch, uri);
}
response = await httpClient.SendRequestAsync(requestMessage).AsTask(cancellationTokenSource.Token);
var rdModel = ProcessResponseData(response);
return await Handle401Error(rdModel, response, postData, url, requestMehtod, isDownloadSite, OnSendRequestProgress, requestData);
}
The above code fine to send JSON data to the same API and works fine. But I need to know how to send just a string in the body. Thank for the consideration
NOTE: App uses HttpClient from Windows.Web.Http and will not be able to use anything inside System.Net.Http namespace.
The answer is given by the #gusman and #Simon Wilson. Just to amend to their answer, in order to be able to send a string in the request body, the string needs to be within double-quotes.
var requestData = "\"hello world\"";
var request = new HttpRequestMessage(HttpMethod.Post, uri)
{
Content = new HttpStringContent(requestData, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json")
};
response = await httpClient.SendRequestAsync(request);
This worked in my scenario.

How do I post data in http header from MVC to webapi post method

I am creating prototype of application where in I am trying to send data in request header and body from C# MVC Controller and also created web api project Post action to process the request.
My code goes like this::
MVC Project code to Post Request:
public class HomeController : Controller
{
public async Task<ActionResult> Index()
{
VM VM = new VM();
VM.Name = " TEST Name";
VM.Address = " TEST Address ";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:58297");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("username","test");
var json = JsonConvert.SerializeObject(VM);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var result1 = await client.PostAsync("api/Values/Post", content);
}
return View();
}
}
My code in WEB API project :
// POST api/values
public IHttpActionResult Post([FromBody]API.VM vm)
{
try
{
HttpRequestMessage re = new HttpRequestMessage();
StreamWriter sw = new StreamWriter(#"E:\Apple\txt.log", false);
var headers = re.Headers;
string token = "";
if (headers.Contains("username"))
{
token = headers.GetValues("username").First();
}
sw.WriteLine("From header" + token);
sw.WriteLine("From BODY" + vm.Name);
sw.WriteLine("From BODY" + vm.Address);
sw.WriteLine("Line2");
sw.Close();
return Ok("Success");
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
What I have understood is [FromBody]API.VM vm gets data from Http request body which means vm object is getting data from HTTP Request body.I am able to get request body. I am not able to understand how do I pass data in header from MVC controller (I want to pass JSON Data) and retrieve data in WEB Api post method?
I have used client.DefaultRequestHeaders.Add("username","test"); in MVC project to pass header data and
HttpRequestMessage re = new HttpRequestMessage();
var headers = re.Headers;
string token = "";
if (headers.Contains("username"))
{
token = headers.GetValues("username").First();
}
in WEB API project to get data but I am not able to get username value.
In order to get your data via headers, you would need to enable CORS: Install-Package Microsoft.AspNet.WebApi.Cors in your project and then in your Register method under WebApiConfig.cs, add this line: EnableCors();.
Once done, you can access your header variable as:
IEnumerable<string> values = new List<string>();
actionContext.Request.Headers.TryGetValues("username", out values);
You can get all headers being passed to a method of a web API using below lines inside that web API method:
HttpActionContext actionContext = this.ActionContext;
var headers = actionContext.Request.Headers;

How to get stringContent from server side?

I have a client Call my API service as this:
var paramDiction = new Dictionary<string, string>{{"datefROM", "2018/1/1"}};
string content = JsonConvert.SerializeObject(paramDiction);
var stringContent = new StringContent(content, Encoding.UTF8, "application/json");
// call the API service
var x = await _httpClient.PostAsync(url, stringContent);
I tried many ways to get the stringContent from Server Side, but still can't get it. I'm I on the wrong way?
[HttpPost]
[Route("GetStringContent")]
public IActionResult GetStringContent()
{
var stringContent = Request.HttpContext.ToString();
return stringContent;
}
Don't know why the Request here is a httpRequest, only have the HTTPContext and this httpContent can't read the content out like
Request.Content.ReadAsStringAsync();
First of all for API Methods you normally return a HttpResponseMessage that you can create with Request.CreateResponse(HttpStatusCode, Message).
Now to your question, in Asp.Net an API Method has parameters according to what you're expecting to be sent. For Example in your case your Method signatrue would look like this public HttpResponseMessage GetStringContent([FromBody] Dictionary<string, string> stringContent). The [FromBody] Attribute is used in Post Methods to signal that the Content is coming from the request body

Custom header to HttpClient request

How do I add a custom header to a HttpClient request? I am using PostAsJsonAsync method to post the JSON. The custom header that I would need to be added is
"X-Version: 1"
This is what I have done so far:
using (var client = new HttpClient()) {
client.BaseAddress = new Uri("https://api.clickatell.com/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "xxxxxxxxxxxxxxxxxxxx");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.PostAsJsonAsync("rest/message", svm).Result;
}
I have found the answer to my question.
client.DefaultRequestHeaders.Add("X-Version","1");
That should add a custom header to your request
Here is an answer based on that by Anubis (which is a better approach as it doesn't modify the headers for every request) but which is more equivalent to the code in the original question:
using Newtonsoft.Json;
...
var client = new HttpClient();
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.clickatell.com/rest/message"),
Headers = {
{ HttpRequestHeader.Authorization.ToString(), "Bearer xxxxxxxxxxxxxxxxxxx" },
{ HttpRequestHeader.Accept.ToString(), "application/json" },
{ "X-Version", "1" }
},
Content = new StringContent(JsonConvert.SerializeObject(svm))
};
var response = client.SendAsync(httpRequestMessage).Result;
var request = new HttpRequestMessage {
RequestUri = new Uri("[your request url string]"),
Method = HttpMethod.Post,
Headers = {
{ "X-Version", "1" } // HERE IS HOW TO ADD HEADERS,
{ HttpRequestHeader.Authorization.ToString(), "[your authorization token]" },
{ HttpRequestHeader.ContentType.ToString(), "multipart/mixed" },//use this content type if you want to send more than one content type
},
Content = new MultipartContent { // Just example of request sending multipart request
new ObjectContent<[YOUR JSON OBJECT TYPE]>(
new [YOUR JSON OBJECT TYPE INSTANCE](...){...},
new JsonMediaTypeFormatter(),
"application/json"), // this will add 'Content-Type' header for the first part of request
new ByteArrayContent([BINARY DATA]) {
Headers = { // this will add headers for the second part of request
{ "Content-Type", "application/Executable" },
{ "Content-Disposition", "form-data; filename=\"test.pdf\"" },
},
},
},
};
There is a Headers property in the HttpRequestMessage class. You can add custom headers there, which will be sent with each HTTP request. The DefaultRequestHeaders in the HttpClient class, on the other hand, sets headers to be sent with each request sent using that client object, hence the name Default Request Headers.
Hope this makes things more clear, at least for someone seeing this answer in future.
I have added x-api-version in HttpClient headers as below :
var client = new HttpClient(httpClientHandler)
{
BaseAddress = new Uri(callingUrl)
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("x-api-version", v2);
My two cents. I agree with heug. The accepted answer is a mind bender. Let's take a step back.
Default headers apply to all requests made by a particular HttpClient. Hence you would use default headers for shared headers.
_client.DefaultRequestHeaders.UserAgent.ParseAdd(_options.UserAgent);
However, we sometimes need headers specific to a certain request. We would therefore use something like this in the method:
public static async Task<HttpResponseMessage> GetWithHeadersAsync(this
HttpClient httpClient, string requestUri, Dictionary<string, string> headers)
{
using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
{
foreach(var header in headers)
{
request.Headers.Add(header.Key, header.Value);
}
return await httpClient.SendAsync(request);
}
}
If you only need one additional non-default header you would simply use:
request.Headers.Add("X-Version","1")
For more help:
How to add request headers when using HttpClient
Also you can use HttpClient.PostAsync method:
using (HttpClient http_client = new HttpClient())
{
StringContent string_content = new StringContent(JsonSerializer.Serialize("{\"field\":\"field_value\"}"));
string_content.Headers.Add("X-Version","1");
using (HttpResponseMessage response = await http_client.PostAsync("http://127.0.0.1/apiMethodName", string_content))
{
if (response.IsSuccessStatusCode)
{
Console.WriteLine($"Response status code: {response.StatusCode}");
}
else
{
Console.WriteLine($"Error status code: {response.StatusCode}");
}
}
}
Just in case someone is wondering how to call httpClient.GetStreamAsync() which does not have an overload which takes HttpRequestMessage to provide custom headers you can use the above code given by #Anubis and call
await response.Content.ReadAsStreamAsync()
Especially useful if you are returning a blob url with Range Header as a FileStreamResult

.NET HttpClient Request Content-Type

I'm not sure, but it appears to me that the default implementation of .NET HttpClient library is flawed. It looks like it sets the Content-Type request value to "text/html" on a PostAsJsonAsync call. I've tried to reset the request value, but not sure if I'm doing this correctly. Any suggestions.
public async Task<string> SendPost(Model model)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.PostAsJsonAsync(Url + "api/foo/", model);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
You should set the content type. With the Accept you define what you want as response.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
The Accept request-header field can be used to specify certain media types which are acceptable for the response. Accept headers can be used to indicate that the request is specifically limited to a small set of desired types, as in the case of a request for an in-line image.
public async Task<string> SendPost(Model model)
{
var client = new HttpClient(); //You should extract this and reuse the same instance multiple times.
var request = new HttpRequestMessage(HttpMethod.Post, Url + "api/foo");
using(var content = new StringContent(Serialize(model), Encoding.UTF8, "application/json"))
{
request.Content = content;
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}

Categories