Send IFileForm to API with JSON - c#

I'm receiving a IFormFile object from an API POST request, and I'm trying to pass that file through to another API endpoint via a POST request with some JSON attached.
I am able to embed the image inside the request, but the server I'm sending to always returns a 500. I believe the issue the fact that I'm sending the JSON and the IFormFile together, as when I send one or the other it works okay (albeit, I'm not receiving the 200 response I want due to one or the other being missing).
Here is the code I'm using to post the data:
public async Task<APIResponse<T>> PostForm<T>(string baseURL, string apiName, IFormFile file, string jsonToPost = "", Dictionary<string, string> headers = null) where T : class
{
using (var client = new HttpClient() { BaseAddress = new Uri(baseURL) })
{
client.BaseAddress = new Uri(baseURL);
HttpResponseMessage response = null;
if (headers != null)
{
foreach (var header in headers)
{
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
}
try
{
var multiContent = new MultipartFormDataContent();
var fileStreamContent = new StreamContent(file.OpenReadStream());
multiContent.Add(fileStreamContent, "file", file.FileName);
multiContent.Add(new StringContent(jsonToPost,System.Text.Encoding.UTF8, "application/json"));
response = await client.PostAsync(apiName, multiContent);
return new APIResponse<T>(JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync()), null, (int)response.StatusCode);
}
catch
{
return new APIResponse<T>(null, await response.Content.ReadAsStringAsync(), (int)response.StatusCode);
}
}
}
And here is what the JSON looks like if it helps anyone:
{
"orderId": 694532,
"type": "4x6",
"copies": 1,
"sizing": "Crop",
"priceToUser": 4000,
"md5hash": "5fed252e505f8542b38d9c0b1f221a71"
}
Edit - Updated code:
public async Task<APIResponse<T>> PostForm<T>(string baseURL, string apiName, IFormFile file, string jsonToPost = "", Dictionary<string, string> headers = null) where T : class
{
var client = new HttpClient();
client.BaseAddress = new Uri(baseURL);
HttpResponseMessage response = null;
if (headers != null)
{
foreach (var header in headers)
{
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
}
try
{
var multiContent = new MultipartFormDataContent();
multiContent.Add(new StringContent(jsonToPost,System.Text.Encoding.UTF8, "application/json"));
multiContent.Add(GetByteArray(file), "file", file.FileName);
response = await client.PostAsync(apiName, multiContent);
return new APIResponse<T>(JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync()), null, (int)response.StatusCode);
}
catch
{
return new APIResponse<T>(null, await response.Content.ReadAsStringAsync(), (int)response.StatusCode);
}
}
private ByteArrayContent GetByteArray(IFormFile file){
byte[] data;
var br = new BinaryReader(file.OpenReadStream());
data = br.ReadBytes((int)file.OpenReadStream().Length);
return new ByteArrayContent(data);
}

Related

Sending Multiple Files in a single Request to API

I am fairly new to API's. I am writing a "simple" API that will convert .docx files to .pdf files and return the pdf's back to the client for saving. I have the code working for a single file but I wanted to code the API to handle multiple files in a single request. Now the API is not receiving the request. I can provide the working code with a single file if requested.
I am sure I am missing something simple. Please see below and see if anyone see's something that I could be doing better or why the API is not receiving the POST request.
Client:
List<string> documents = new List<string>();
private async void btnConvert_Click(object sender, EventArgs e)
{
using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new Uri(BaseApiUrl);
//client.DefaultRequestHeaders.Add("Accept", "application/json");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, BaseApiUrl + ApiUrl);
foreach (string s in docPaths)
{
byte[] bte;
bte = File.ReadAllBytes(docPath);
string data = JsonConvert.SerializeObject(Convert.ToBase64String(bte));
documents.Add(data);
}
using (var formData = new MultipartFormDataContent())
{
foreach (string s in documents)
{
//add content to form data
formData.Add(new StringContent(s, Encoding.UTF8, "application/json"));
}
// List of Http Reponse Messages
var conversions = documents.Select(doc => client.PostAsync(BaseApiUrl + ApiUrl, formData)).ToList();
//Wait for all the requests to finish
await Task.WhenAll(conversions);
//Get the responses
var responses = conversions.Select
(
task => task.Result
);
foreach (var r in responses)
{
// Extract the message body
var s = await r.Content.ReadAsStringAsync();
SimpleResponse res = JsonConvert.DeserializeObject<SimpleResponse>(s);
if (res.Success)
{
byte[] pdf = Convert.FromBase64String(res.Result.ToString());
// Save the PDF here
}
else
{
// Log issue
}
}
}
}
API: This is not getting the request so this function is not complete. I need to figure out why it not being hit.
[HttpPost]
public async Task<List<SimpleResponse>> Post([FromBody]string request)
{
var response = new List<SimpleResponse>();
Converter convert = new Converter();
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
foreach (var requestContents in provider.Contents)
{
try
{
//var result = convert.CovertDocToPDF(requestContents, WebConfigurationManager.AppSettings["tempDocPath"], WebConfigurationManager.AppSettings["tempPdfPath"]);
//response.Add(new SimpleResponse() { Result = result, Success = true });
}
catch (Exception ex)
{
response.Add(new SimpleResponse() { Success = false, Exception = ex, Errors = new List<string>() { string.Format("{0}, {1}", ex.Message, ex.InnerException?.Message ?? "") } });
}
}
return response;
}
SimpleResponse Model:
public class SimpleResponse
{
public object Result { get; set; }
public bool Success { get; set; }
public Exception Exception { get; set; }
public List<string> Errors { get; set; }
}
UPDATE
Did suggestions made by #jdweng and I am getting a null response on the API POST
Client:
public async void btnConvert_Click(object sender, EventArgs e)
{
using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new Uri(BaseApiUrl);
client.DefaultRequestHeaders.Add("Accept", "application/json");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));//application/json
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, BaseApiUrl + ApiUrl);
List<string> requests = new List<string>();
byte[] bte;
// New Code per the suggestion
foreach (string s in docPaths)
{
bte = File.ReadAllBytes(s);
requests.Add(Convert.ToBase64String(bte));
}
// End new code
string data = JsonConvert.SerializeObject(requests);
request.Content = new StringContent(data, Encoding.UTF8, "application/json");
HttpResponseMessage response1 = client.PostAsync(BaseApiUrl + ApiUrl, request.Content).Result;
Task<string> json = response1.Content.ReadAsStringAsync();
SimpleResponse response = JsonConvert.DeserializeObject<SimpleResponse>(json.Result);
//result = JsonConvert.DeserializeObject(result).ToString();
if (response.Success)
{
bte = Convert.FromBase64String(response.Result.ToString());
if (File.Exists(tempPdfPath))
{
File.Delete(tempPdfPath);
}
System.IO.File.WriteAllBytes(tempPdfPath, bte);
}
else
{
}
}
}
Server:
[HttpPost]
public async Task<List<SimpleResponse>> Post([FromBody]string request)
{
// The request in NULL....
List<SimpleResponse> responses = new List<SimpleResponse>();
List<string> resp = JsonConvert.DeserializeObject(request) as List<string>;
try
{
Converter convert = new Converter();
foreach (string s in resp)
{
var result = convert.CovertDocToPDF(request, WebConfigurationManager.AppSettings["tempDocPath"], WebConfigurationManager.AppSettings["tempPdfPath"]);
responses.Add(new SimpleResponse()
{
Result = result,
Success = true
});
}
}
catch (Exception ex)
{
responses.Add(new SimpleResponse()
{
Result = null,
Success = true,
Exception = ex,
Errors = new List<string>() { string.Format("{0}, {1}", ex.Message, ex.InnerException?.Message ?? "") }
});
}
return responses;
}
I have finally solved the issues and can now successfully send multiple .docx files to the API and get the .pdf files back from the API. Now I want to figure out how to send each files on it's own thread instead of all together.
Client:
public async void btnConvert_Click(object sender, EventArgs e)
{
using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new Uri(BaseApiUrl);
client.DefaultRequestHeaders.Add("Accept", "application/json");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, BaseApiUrl + ApiUrl);
List<string> requests = new List<string>();
byte[] bte;
foreach (string s in docPaths)
{
bte = File.ReadAllBytes(s);
requests.Add(Convert.ToBase64String(bte));
}
var data = JsonConvert.SerializeObject(requests);
request.Content = new StringContent(data, Encoding.UTF8, "application/json");
HttpResponseMessage response1 = await client.PostAsync(BaseApiUrl + ApiUrl, request.Content);
Task<string> json = response1.Content.ReadAsStringAsync();
var response = JsonConvert.DeserializeObject<List<SimpleResponse>>(json.Result);
foreach (SimpleResponse sr in response)
{
if (sr.Success)
{
bte = Convert.FromBase64String(sr.Result.ToString());
string rs = RandomString(16, true);
string pdfFileName = tempPdfPath + rs + ".pdf";
if (File.Exists(pdfFileName))
{
File.Delete(pdfFileName);
}
System.IO.File.WriteAllBytes(pdfFileName, bte);
}
else
{
}
}
}
}
API:
[HttpPost]
public async Task<List<SimpleResponse>> Post([FromBody] List<string> request)
{
List<SimpleResponse> responses = new List<SimpleResponse>();
try
{
Converter convert = new Converter();
foreach (string s in request)
{
var result = convert.CovertDocToPDF(s, WebConfigurationManager.AppSettings["tempDocPath"], WebConfigurationManager.AppSettings["tempPdfPath"]);
responses.Add(new SimpleResponse()
{
Result = result,
Success = true
});
}
}
catch (Exception ex)
{
responses.Add(new SimpleResponse()
{
Result = null,
Success = true,
Exception = ex,
Errors = new List<string>() { string.Format("{0}, {1}", ex.Message, ex.InnerException?.Message ?? "") }
});
}
return responses;
}

How to implement WebClient.UploadFileAsync with HttpClient? [duplicate]

Does anyone know how to use the HttpClient in .Net 4.5 with multipart/form-data upload?
I couldn't find any examples on the internet.
my result looks like this:
public static async Task<string> Upload(byte[] image)
{
using (var client = new HttpClient())
{
using (var content =
new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)))
{
content.Add(new StreamContent(new MemoryStream(image)), "bilddatei", "upload.jpg");
using (
var message =
await client.PostAsync("http://www.directupload.net/index.php?mode=upload", content))
{
var input = await message.Content.ReadAsStringAsync();
return !string.IsNullOrWhiteSpace(input) ? Regex.Match(input, #"http://\w*\.directupload\.net/images/\d*/\w*\.[a-z]{3}").Value : null;
}
}
}
}
It works more or less like this (example using an image/jpg file):
async public Task<HttpResponseMessage> UploadImage(string url, byte[] ImageData)
{
var requestContent = new MultipartFormDataContent();
// here you can specify boundary if you need---^
var imageContent = new ByteArrayContent(ImageData);
imageContent.Headers.ContentType =
MediaTypeHeaderValue.Parse("image/jpeg");
requestContent.Add(imageContent, "image", "image.jpg");
return await client.PostAsync(url, requestContent);
}
(You can requestContent.Add() whatever you want, take a look at the HttpContent descendant to see available types to pass in)
When completed, you'll find the response content inside HttpResponseMessage.Content that you can consume with HttpContent.ReadAs*Async.
This is an example of how to post string and file stream with HTTPClient using MultipartFormDataContent. The Content-Disposition and Content-Type need to be specified for each HTTPContent:
Here's my example. Hope it helps:
private static void Upload()
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("User-Agent", "CBS Brightcove API Service");
using (var content = new MultipartFormDataContent())
{
var path = #"C:\B2BAssetRoot\files\596086\596086.1.mp4";
string assetName = Path.GetFileName(path);
var request = new HTTPBrightCoveRequest()
{
Method = "create_video",
Parameters = new Params()
{
CreateMultipleRenditions = "true",
EncodeTo = EncodeTo.Mp4.ToString().ToUpper(),
Token = "x8sLalfXacgn-4CzhTBm7uaCxVAPjvKqTf1oXpwLVYYoCkejZUsYtg..",
Video = new Video()
{
Name = assetName,
ReferenceId = Guid.NewGuid().ToString(),
ShortDescription = assetName
}
}
};
//Content-Disposition: form-data; name="json"
var stringContent = new StringContent(JsonConvert.SerializeObject(request));
stringContent.Headers.Add("Content-Disposition", "form-data; name=\"json\"");
content.Add(stringContent, "json");
FileStream fs = File.OpenRead(path);
var streamContent = new StreamContent(fs);
streamContent.Headers.Add("Content-Type", "application/octet-stream");
//Content-Disposition: form-data; name="file"; filename="C:\B2BAssetRoot\files\596090\596090.1.mp4";
streamContent.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"" + Path.GetFileName(path) + "\"");
content.Add(streamContent, "file", Path.GetFileName(path));
//content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
Task<HttpResponseMessage> message = client.PostAsync("http://api.brightcove.com/services/post", content);
var input = message.Result.Content.ReadAsStringAsync();
Console.WriteLine(input.Result);
Console.Read();
}
}
}
Try this its working for me.
private static async Task<object> Upload(string actionUrl)
{
Image newImage = Image.FromFile(#"Absolute Path of image");
ImageConverter _imageConverter = new ImageConverter();
byte[] paramFileStream= (byte[])_imageConverter.ConvertTo(newImage, typeof(byte[]));
var formContent = new MultipartFormDataContent
{
// Send form text values here
{new StringContent("value1"),"key1"},
{new StringContent("value2"),"key2" },
// Send Image Here
{new StreamContent(new MemoryStream(paramFileStream)),"imagekey","filename.jpg"}
};
var myHttpClient = new HttpClient();
var response = await myHttpClient.PostAsync(actionUrl.ToString(), formContent);
string stringContent = await response.Content.ReadAsStringAsync();
return response;
}
Here is another example on how to use HttpClient to upload a multipart/form-data.
It uploads a file to a REST API and includes the file itself (e.g. a JPG) and additional API parameters. The file is directly uploaded from local disk via FileStream.
See here for the full example including additional API specific logic.
public static async Task UploadFileAsync(string token, string path, string channels)
{
// we need to send a request with multipart/form-data
var multiForm = new MultipartFormDataContent();
// add API method parameters
multiForm.Add(new StringContent(token), "token");
multiForm.Add(new StringContent(channels), "channels");
// add file and directly upload it
FileStream fs = File.OpenRead(path);
multiForm.Add(new StreamContent(fs), "file", Path.GetFileName(path));
// send request to API
var url = "https://slack.com/api/files.upload";
var response = await client.PostAsync(url, multiForm);
}
Here's a complete sample that worked for me. The boundary value in the request is added automatically by .NET.
var url = "http://localhost/api/v1/yourendpointhere";
var filePath = #"C:\path\to\image.jpg";
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
FileStream fs = File.OpenRead(filePath);
var streamContent = new StreamContent(fs);
var imageContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
form.Add(imageContent, "image", Path.GetFileName(filePath));
var response = httpClient.PostAsync(url, form).Result;
Example with preloader Dotnet 3.0 Core
ProgressMessageHandler processMessageHander = new ProgressMessageHandler();
processMessageHander.HttpSendProgress += (s, e) =>
{
if (e.ProgressPercentage > 0)
{
ProgressPercentage = e.ProgressPercentage;
TotalBytes = e.TotalBytes;
progressAction?.Invoke(progressFile);
}
};
using (var client = HttpClientFactory.Create(processMessageHander))
{
var uri = new Uri(transfer.BackEndUrl);
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", AccessToken);
using (MultipartFormDataContent multiForm = new MultipartFormDataContent())
{
multiForm.Add(new StringContent(FileId), "FileId");
multiForm.Add(new StringContent(FileName), "FileName");
string hash = "";
using (MD5 md5Hash = MD5.Create())
{
var sb = new StringBuilder();
foreach (var data in md5Hash.ComputeHash(File.ReadAllBytes(FullName)))
{
sb.Append(data.ToString("x2"));
}
hash = result.ToString();
}
multiForm.Add(new StringContent(hash), "Hash");
using (FileStream fs = File.OpenRead(FullName))
{
multiForm.Add(new StreamContent(fs), "file", Path.GetFileName(FullName));
var response = await client.PostAsync(uri, multiForm);
progressFile.Message = response.ToString();
if (response.IsSuccessStatusCode) {
progressAction?.Invoke(progressFile);
} else {
progressErrorAction?.Invoke(progressFile);
}
response.EnsureSuccessStatusCode();
}
}
}
I'm adding a code snippet which shows on how to post a file to an API which has been exposed over DELETE http verb. This is not a common case to upload a file with DELETE http verb but it is allowed. I've assumed Windows NTLM authentication for authorizing the call.
The problem that one might face is that all the overloads of HttpClient.DeleteAsync method have no parameters for HttpContent the way we get it in PostAsync method
var requestUri = new Uri("http://UrlOfTheApi");
using (var streamToPost = new MemoryStream("C:\temp.txt"))
using (var fileStreamContent = new StreamContent(streamToPost))
using (var httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true })
using (var httpClient = new HttpClient(httpClientHandler, true))
using (var requestMessage = new HttpRequestMessage(HttpMethod.Delete, requestUri))
using (var formDataContent = new MultipartFormDataContent())
{
formDataContent.Add(fileStreamContent, "myFile", "temp.txt");
requestMessage.Content = formDataContent;
var response = httpClient.SendAsync(requestMessage).GetAwaiter().GetResult();
if (response.IsSuccessStatusCode)
{
// File upload was successfull
}
else
{
var erroResult = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
throw new Exception("Error on the server : " + erroResult);
}
}
You need below namespaces at the top of your C# file:
using System;
using System.Net;
using System.IO;
using System.Net.Http;
P.S. You are seeing a number of using blocks(IDisposable pattern) in the above code snippet which doesn't look very clean. Unfortunately, the syntax of using construct doesn't support initializing multiple variables in single statement.
X509Certificate clientKey1 = null;
clientKey1 = new X509Certificate(AppSetting["certificatePath"],
AppSetting["pswd"]);
string url = "https://EndPointAddress";
FileStream fs = File.OpenRead(FilePath);
var streamContent = new StreamContent(fs);
var FileContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
FileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("ContentType");
var handler = new WebRequestHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(clientKey1);
handler.ServerCertificateValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) =>
{
return true;
};
using (var client = new HttpClient(handler))
{
// Post it
HttpResponseMessage httpResponseMessage = client.PostAsync(url, FileContent).Result;
if (!httpResponseMessage.IsSuccessStatusCode)
{
string ss = httpResponseMessage.StatusCode.ToString();
}
}
public async Task<object> PassImageWithText(IFormFile files)
{
byte[] data;
string result = "";
ByteArrayContent bytes;
MultipartFormDataContent multiForm = new MultipartFormDataContent();
try
{
using (var client = new HttpClient())
{
using (var br = new BinaryReader(files.OpenReadStream()))
{
data = br.ReadBytes((int)files.OpenReadStream().Length);
}
bytes = new ByteArrayContent(data);
multiForm.Add(bytes, "files", files.FileName);
multiForm.Add(new StringContent("value1"), "key1");
multiForm.Add(new StringContent("value2"), "key2");
var res = await client.PostAsync(_MEDIA_ADD_IMG_URL, multiForm);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return result;
}

Simple Post Request with file and parameters

I have this code, to make a post request to a Local Courier API.
public async Task ImportAwbIntegrat()
{
string fisier = File.ReadAllText(#"F:\Read\model.csv");
var values = new Dictionary<string, string>
{
{ "username", "clienttest" },
{ "client_id", "70321588" },
{"user_pass", "testing" },
{"fisier", fisier }
};
HttpClient client = new HttpClient();
try
{
var content = new FormUrlEncodedContent(values);
string methodurl = "https://www.selfawb.ro/import_awb_integrat.php";
var response = await client.PostAsync(methodurl, content);
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response);
}
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
}
catch (Exception ex)
{
string message = ex.Message;
Console.WriteLine(message); ;
}
}
The request it`s working,
response value = {Method: POST, RequestUri: 'https://www.selfawb.ro/import_awb_integrat.php', Version: 1.1, Content: System.Net.Http.FormUrlEncodedContent, Headers:
{
Content-Type: application/x-www-form-urlencoded
Content-Length: 442
}}
but inside the responseString i have this message:
"The file was not uploaded. It asks you, try again."
I think this happens because the server want a .csv file with value separated by ; but i send it the values from file, not the file itself.
Try this code
public async Task ImportAwbIntegrat()
{
string fisier = File.ReadAllText(#"F:\Read\model.csv");
var values = new Dictionary<string, string>
{
{ "username", "clienttest" },
{ "client_id", "111111" },
{"user_pass", "testing" }
};
var image = File.ReadAllBytes(#"F:\Read\model.csv");
using (var client = new HttpClient())
{
using (var content =
new MultipartFormDataContent())
{
content.Add(new StreamContent(new MemoryStream(image)), "fisier", "model.csv");
foreach (KeyValuePair<string, string> param in values)
{
content.Add(new StringContent(param.Value), $"\"{param.Key}\"");
}
using (var response = await client.PostAsync("https://www.selfawb.ro/import_awb_integrat.php", content))
{
var input = await response.Content.ReadAsStringAsync();
var responseString = await response.Content.ReadAsStringAsync();
}
}
}
}

Xamarin Sending POST Data

I am attempting to send POST data to my server and get back a response. For some reason, no POST data is actually getting sent. A request is being sent to my server but the POST array is empty.
Here is my code for sending the request:
public class GlobalMethods
{
public async Task<string> callAjax(string mthd,NameValueCollection parameters)
{
var client = new HttpClient();
var content = JsonConvert.SerializeObject(parameters);
var result = await client.PostAsync("http://dev.adex-intl.com/adex/mvc/receiving/"+mthd, new StringContent(content)).ConfigureAwait(false);
var tokenJson = "";
if (result.IsSuccessStatusCode)
{
tokenJson = await result.Content.ReadAsStringAsync();
}
return tokenJson;
}
}
And here is my code that calls the above method:
public void loginPressed(object sender, EventArgs e)
{
if(String.IsNullOrEmpty(badge.Text)) {
DisplayAlert("Error", "Enter your badge number", "Ok");
} else {
IsBusy = true;
NameValueCollection parameters = new NameValueCollection();
parameters["badgetNumber"] = badge.Text;
GlobalMethods globalMethods = new GlobalMethods();
var results = globalMethods.callAjax("login", parameters);
}
}
I'm not sure what I'm doing wrong. Also, I'm a newbie to Xamarin and C# so I'm not even sure if the way I am attempting to do things is the best way.
You haven't specify the type of content that you want to send, in your case it's 'application/json', you can set it like that:
"var client = new HttpClient();
var content = new StringContent(JsonConvert.SerializeObject(parameters));
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");". Also, I would suggest you to write code like that:
var uri = new Uri(url);
using (var body = new StringContent(JsonConvert.SerializeObject(data)))
{
body.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var request = new HttpRequestMessage
{
Version = new Version(1, 0),
Content = body,
Method = HttpMethod.Post,
RequestUri = uri
};
try
{
using (var response = await _client.SendAsync(request,cancellationToken))
{
if (response.IsSuccessStatusCode)
{
//Deal with success response
}
else
{
//Deal with non-success response
}
}
}
catch(Exception ex)
{
//Deal with exception.
}
}
You can use PostAsync for async sending data to server. your code should be something like this:
HttpClient client = new HttpClient();
var values = new Dictionary<string, string>
{
{ "p1", "data1" },
{ "p2", "data2" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://www.example.com/index.php", content);
var responseString = await response.Content.ReadAsStringAsync();

How to post JSON with HttpClient using C#?

I have no idea how to POST JSON with HttpClient. I find some solution, like this, but I have to use HttpClient, cause of async and have to add a header.
This is my code below. Any idea how to fix it?
List<Order> list = new List<Order> { new Order() { Name = "CreatedTime", OrderBy = 1 } };
Queues items = new Queues { Orders = list };
var values = new Dictionary<string, string> { { "Orders", JsonConvert.SerializeObject(list) } };
var content = new FormUrlEncodedContent(values);
//HttpContent cc = new StringContent(JsonConvert.SerializeObject(items));
_msg = await _client.PostAsync(input, content);
//_msg = await _client.PostAsync(input, cc);
var response = await _msg.Content.ReadAsStringAsync();
You can use the method PostAsJsonAsync which can be found in the extensions assemblies:
System.Net.Http.Formatting.dll
Example
public static async Task SendJsonDemo(object content)
{
using(var client = new HttpClient())
{
var response = await client.PostAsJsonAsync("https://example.com", content);
}
}
If you want to add custom headers to the request, add it to DefaultRequestHeaders:
client.DefaultRequestHeaders.Add("mycustom", "header1");
You can send any type of request like as
public static async Task<HttpResponseMessage> SendRequest(HttpMethod method, string endPoint, string accessToken, dynamic content = null)
{
HttpResponseMessage response = null;
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(method, endPoint))
{
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
if (content != null)
{
string c;
if (content is string)
c = content;
else
c = JsonConvert.SerializeObject(content);
request.Content = new StringContent(c, Encoding.UTF8, "application/json");
}
response = await client.SendAsync(request).ConfigureAwait(false);
}
}
return response;
}

Categories

Resources