Unable to get header "Content-Disposition" with httpclient in C# - c#

SCENARIO:
First of all, please consider I'm using HttpClient class, not WebRequest, I know that there is a lot of related question here but all answers are for WebRequest.
I made a Web Api Application that set in this way the following header in order to download a .txt file:
resp.Content = new StringContent(result, System.Text.Encoding.UTF8, "text/plain");
resp.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = _datacontext.GetAppConfig("814FileNameHeader") + DateTime.Now.ToString("yyyyMMdd") + ".txt"
};
resp.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
After I made an HttpClient from other application to connect to this method.
Everything is working, retrieves 200 and the content of the file. But I can't get the header in order to read the filename.
TRIES MADE:
Working with a REST Client I can read the following header attribute:
Content-Disposition: attachment; filename=814Entes_PG_20160114.txt
and from the code I could debug it and I found that the header is in "invalidHeaders" but I can't reach the value:
QUESTION:
How can I set up this and getting without any doubt from the client?
UPDATE:
These are my tries to get the header:
The original:
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(uri);
string authentication = string.Concat(authenticationArgs[0], ":", authenticationArgs[1]);
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Basic " + Base64Encode(authentication));
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, "Report/" + type);
req.Content = new StringContent("");
HttpResponseMessage response = await httpClient.SendAsync(req);
Console.WriteLine(response.StatusCode);
if (response.IsSuccessStatusCode)
{
string stream = response.Content.ReadAsStringAsync().Result;
Console.Write("Respuesta servicio: " + stream);
Console.WriteLine(stream);
string cp = response.Headers.GetValues("Content-Disposition").ToString();
}
The second one I tried with some SO investigation:
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(uri);
string authentication = string.Concat(authenticationArgs[0], ":", authenticationArgs[1]);
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Basic " + Base64Encode(authentication));
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, "Report/" + type);
req.Content = new StringContent("");
HttpResponseMessage response = await httpClient.SendAsync(req);
Console.WriteLine(response.StatusCode);
if (response.IsSuccessStatusCode)
{
string stream = response.Content.ReadAsStringAsync().Result;
Console.Write("Respuesta servicio: " + stream);
Console.WriteLine(stream);
string cp = "";
HttpHeaders headers = response.Headers;
IEnumerable<string> values;
if (headers.TryGetValues("Content-Disposition", out values))
{
cp = values.ToString();
}
}

If you are trying to get the headers of the content, it should be from response.Content.Headers

As per #terbubbs you need response.Content.Headers.
But also code needs to be - for the first code sample:
string cp = response.Result.Content.Headers.GetValues("Content-Disposition").ToList()[0];
And for the second:
cp = values.FirstOrDefault().ToString();
Otherwise the result is System.String[]

Related

How to convert WebClient to HttpClient C# WinForms

I need to convert the webclient code which is obsolte to httpclient.
using WebClient Client = new();
Client.Headers["User-Agent"] = CompanyName + "/" + ProductName;
byte[] responseBytes = Client.UploadFile("http://blahblah.com/upload.php", fileimage);
string response = Encoding.Default.GetString(responseBytes);
_ = MessageBox.Show(response, Text);
I need the exact same way to do this. I have seen other answers but none meet my needs.
1- read AllByte of file into upfilebytes array
2-create new HttpClient and MultipartFormDataContent
3- add byte array to content
4-upload MultipartFormDataContent content async and store response in response.
var upfilebytes = File.ReadAllBytes("fileimage");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", CompanyName + "/" + ProductName);
MultipartFormDataContent content = new MultipartFormDataContent();
ByteArrayContent baContent = new ByteArrayContent(upfilebytes);
content.Add(baContent, "File", "filename.png");
var response = await client.PostAsync("http://blahblah.com/upload.php", content);
var responsestr = await response.Content.ReadAsStringAsync();
MessageBox.Show(response, responsestr);
The simplest way you can upload a file is something like here.However,
it's better to use HttpClientFactory to generate httpclient instance.
var client = new HttpClient
{
BaseAddress = new("http://blahblah.com/upload.php")
};
await using var stream = System.IO.File.OpenRead("filePathHere");
using var request = new HttpRequestMessage(HttpMethod.Post, "file");
request.Headers.Add("User-Agent",CompanyName + "/" + ProductName);
using var content = new MultipartFormDataContent
{
{ new StreamContent(stream), "file", "fileNameHere" }
};
request.Content = content;
var response = await client.SendAsync(request);
MessageBox.Show(response, Text);

Including Authentication in the Header of a POST Request using ASP.NET Core

I'm trying to make a request to receive a session Id to integrate with a payment gateway.
var m = System.Text.Encoding.Unicode.GetBytes("merchant." + merchant_Id + ":" + merchant_pass);
var b64Val = Convert.ToBase64String(m);
var SerSession = JsonConvert.SerializeObject(sessionRequest);
var client = new HttpClient();
string _ContentType = "application/json";
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_ContentType));
client.DefaultRequestHeaders.Add("Authorization", String.Format("Basic {0}", b64Val));
var _UserAgent = "d-fens HttpClient";
client.DefaultRequestHeaders.Add("User-Agent", _UserAgent);
HttpContent _Body = new StringContent(SerSession);
]_Body.Headers.ContentType = new MediaTypeHeaderValue(_ContentType);
HttpResponseMessage response;
response = await client.PostAsync(api_URL, _Body);
var content = response.Content.ReadAsStringAsync().Result;
return Ok(content);
I am getting (Invalid credentials) and I am sure the credentials I am using are correct. I have tested them in Python and PHP.
try this
var authenticationString = $"{merchant_Id}:{merchant_pass}";
var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(authenticationString));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString);

Uploading image to ServiceNow in C# via REST API

I am trying to upload image to ServiceNow incident using SNow API provided in this link:
https://developer.servicenow.com/dev.do#!/reference/api/orlando/rest/c_AttachmentAPI#r_AttachmentAPI-POSTmultipart
I've written below C# code to post the image:
string url = "https://mycompany.service-now.com/api/now/attachment/upload/"
, userName = "MyUser", passwd = "MyPassword";
var httpClientHandler = new HttpClientHandler()
{
Credentials = new NetworkCredential(userName, passwd),
};
using (var httpClient = new HttpClient(httpClientHandler))
{
// Add an Accept header for JSON format.
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var multipartContent = new MultipartFormDataContent();
multipartContent.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data");
multipartContent.Add(new StringContent("incident"), "table_name");
multipartContent.Add(new StringContent("f264fd3a1bghghgjjhg8f7b4bcbb6"), "table_sys_id"); // id of my incident
multipartContent.Add(new ByteArrayContent(File.ReadAllBytes("D:\\MyImage.jpeg")), "uploadFile", "MyImage.jpeg");
var response = httpClient.PostAsync(new Uri(url), multipartContent).Result;
string result = response.Content.ReadAsStringAsync().Result;
MessageBox.Show(result);
}
However, I keep getting:
Requested URI does not represent any resource
What could be the problem and how to adjust the code accordingly?
After removing the "/" at the end of the url, and also adding double qoutes around the keys in the headers as I read from this post:
https://community.servicenow.com/community?id=community_question&sys_id=328614ffdb00eb808e7c2926ca9619ad&view_source=searchResult
The final working code is:
string url = "https://mycompany.service-now.com/api/now/attachment/upload"
, userName = "MyUser", passwd = "MyPassword";
var httpClientHandler = new HttpClientHandler()
{
Credentials = new NetworkCredential(userName, passwd),
};
using (var httpClient = new HttpClient(httpClientHandler))
{
// Add an Accept header for JSON format.
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var fileStream = new ByteArrayContent(File.ReadAllBytes("D:\\Image.jpeg"));
fileStream.Headers.Remove("Content-Type");
fileStream.Headers.Add("Content-Type", "application/octet-stream");
fileStream.Headers.Add("Content-Transfer-Encoding", "binary");
fileStream.Headers.Add("Content-Disposition", $"form-data;name=\"uploadFile\"; filename=\"{"Image.jpeg"}\"");
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(new StringContent("incident"), "\"table_name\"");
multipartContent.Add(new StringContent("f264fd3a1bghghgjjhg8f7b4bcbb6"), "\"table_sys_id\"");
multipartContent.Add(fileStream, "uploadFile");
var response = httpClient.PostAsync(new Uri(url), multipartContent).Result;
string result = response.Content.ReadAsStringAsync().Result;
MessageBox.Show(result);
}

C# Converting string to JSON

I am trying to POST to using C# to a JSON payload which I can achieve but I am having trouble understanding how to replace the sample string with my own string.
From the code below you can see I have a string I want to send to my weblink. The code runs fine when I use "{\"text\":\"Hello, World!\"}" for the StringContent but if I try to replace it with the string of output_message it doesn't work. I am trying to work out how I convert my output_message to a format that JSON can recognize.
{
string output_message = "The file " + filename + " has been modified by " + user_modified + " and moved to the " + file_state + " file state. Please review the " + filename + " file and approve or reject.";
PostWebHookAsync(output_message);
Console.ReadLine();
}
static async void PostWebHookAsync(string Aoutput_message)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "www.mywebsitelink"))
{
//request.Content = new StringContent("{\"text\":\"Hello, World!\"}", Encoding.UTF8, "application/json"); // - original do not delete
request.Content = new StringContent(Aoutput_message, Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
}
}
}
I want to replace "{\"text\":\"Hello, World!\"}" with a string
To the best of my knowledge people are moving away from JavaScriptSerializer and towards Json.NET. It's even recommended in the documentation here
The corresponding Json.NET code would look something like:
static async void PostWebHookAsync(string output_message)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "www.mywebsitelink"))
{
string jsonValue = JsonConvert.SerializeObject(new
{
text = output_message
});
request.Content = new StringContent(jsonValue, Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
}
}
}
To use Json.NET you need to install the Newtonsoft.Json nuget package.
The best way is to create an object and serialize it.
To use JavaScriptSerializer you have to add a reference to System.Web.Extensions.dll
So for your problem, we create an anonymous object with a property text we pass the value Aoutput_message
static async void PostWebHookAsync(string Aoutput_message)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "www.mywebsitelink"))
{
//request.Content = new StringContent("{\"text\":\"Hello, World!\"}", Encoding.UTF8, "application/json"); // - original do not delete
string jsonValue = new JavaScriptSerializer().Serialize(new
{
text = Aoutput_message,
});
request.Content = new StringContent(jsonValue, Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
}
}
}
Examples

Cant get Authorized with my API that has a JWT authentication Im Working With Xamarin

Well Im new in Xamarin and I'm developing and App, the authentication is JWT based.
Im using a HttpClient and setting the AuthenticationHeaders but It always returns Unauthorized when I try it on Postman it Works but I can't make it work in my app.
Here is how im trying to do it:
var client = new HttpClient(new HttpClientHandler());
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("JWT", accessToken);
client.BaseAddress = new Uri(urlBase);
var url = string.Format("{0}{1}", servicePrefix, controller);
var response = await client.GetAsync(url);
Try something like this
using (var client = new HttpClient())
{
var uri = new Uri(string.Format($"{<yourURLString>}", string.Empty));
var jsonTransport = "";
var jsonPayload = new StringContent(jsonTransport, Encoding.UTF8, "application/json");
//client.DefaultRequestHeaders.Add("Content-type", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "JWT " + accessToken);
var response = await client.PostAsync(uri, jsonPayload);
string responseContent = await response.Content.ReadAsStringAsync();
}
then deserialize the responseContent to your object using JsonConvert.DeserializeObject
Note: Below are code samples, edit to your own objects
SubscriptionResponse profileResponse = JsonConvert.DeserializeObject<SubscriptionResponse>(responseContent);
then if your method returns something, use the return statement. Something like this
return profileResponse.Data.Subscriptions;
If you're using a get, this could be a guide
var uri = new Uri(string.Format($"{<yourURLHere>}", string.Empty));
client.DefaultRequestHeaders.Add("Authorization", "JWT " + accessToken);
var httpResponse = await client.GetAsync(uri);
var responseContent = await httpResponse.Content.ReadAsStringAsync();
then deserialize your string response
Note: this is a sample - edit to your model (You may use PostMan to get the response format in JSON and model it in C#)
var UserDetailResponse = JsonConvert.DeserializeObject<UserDetail>(responseContent);
return UserDetailResponse;

Categories