Simple Post Request with file and parameters - c#

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();
}
}
}
}

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;
}

I didn't know, why does the server respond with error code 400

My friend write API and sends such request to php
$response = $http->post('http://you-app.com/oauth/token',[
'form_params' => [
'grant_type' => 'password',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'username' => 'my-username',
'password' => 'my-password',
'scope' => '',
],
])
it`s my code (I work at xamarin.ios)
maybe i'm sending the wrong request. (just starting to learn http request)
using (HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) })
{
//create my json
Request json_Request = new Request
{
Url = "http://my_url/oauth/token",
Form_params = new Params
{
Grant_Type = "password",
Client_ID = "my_client_id",
Client_Secret = "my client secret",
Username = "my username",
Password = "my password",
Scope = ""
}
};
HttpContent content = new StringContent(JsonConvert.SerializeObject(json_Request), Encoding.UTF8);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
var response = await client.PostAsync(new Uri("http://my_url/oauth/token"), content);
if (response.IsSuccessStatusCode)
{
var response_From_Server = await response.Content.ReadAsStreamAsync();
return null;
}
else
{
return null;
}
}
i'm use this and server send me 401 error)
var values = new Dictionary<string, string>
{
{"grant_type", "password"},
{"client_id", "client-id"},
{"client_secret", "client-secret"},
{"username", "my username"},
{"password", "my password"},
{"scope", ""},
};
request.Content = new FormUrlEncodedContent(values);
request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
HttpResponseMessage response = await client.PostAsync("http://inv/oauth/token", request.Content);
The way you are creating the request is wrong. Pls see this post
https://stackoverflow.com/a/4015346/1184584
var values = new Dictionary<string, string>
{
{ "thing1", "hello" },
{ "thing2", "world" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://www.example.com/recepticle.aspx", content);
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();

Send IFileForm to API with JSON

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);
}

How to implement a multipart post request in c# wp8.1 (winrt)

Already second day trying to implement a multipart post request, but so far I have failed.
Task: to send 1 or 2 pictures to the server.
Please tell me how to do this in Windows Phone 8.1 (WinRT). Already tried a huge number of links on the Internet, but nothing happened.
p.s. in the description of the API server written that you must submit a request in the following format.
{
"type": "object",
"properties": {
"files": {
"type": "array",
"items": {
"type": "file"
}
}
}
}
Yes, of course. Here is my code. I searched the Internet and eventually tried to implement this. Interestingly, it worked and sent the data to the server. only the North returned the error: "data error", so I sent out in the wrong format. I assume it's because not json created structure, about which I wrote above.
public async static Task<bool> UploadFiles(StorageFile file)
{
var streamData = await file.OpenReadAsync();
var bytes = new byte[streamData.Size];
using (var dataReader = new DataReader(streamData))
{
await dataReader.LoadAsync((uint)streamData.Size);
dataReader.ReadBytes(bytes);
}
System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient();
System.Net.Http.MultipartFormDataContent form = new System.Net.Http.MultipartFormDataContent();
form.Add(new System.Net.Http.StringContent(UserLogin), "username");
form.Add(new System.Net.Http.StringContent(UserPassword), "password");
form.Add(new System.Net.Http.ByteArrayContent(bytes, 0, bytes.Length), "files", "items");
form.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
System.Net.Http.HttpResponseMessage response = await httpClient.PostAsync(UploadFilesURI, form);
response.EnsureSuccessStatusCode();
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;
return true;
}
Sorry for this style of code. Haven't quite figured out how to insert it correctly in the posts
I eventually solved my problem. The code give below
public async static Task<string> UploadFiles(StorageFile[] files)
{
try
{
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("ru"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", "token=" + SessionToken);
var content = new System.Net.Http.MultipartFormDataContent();
foreach (var file in files)
{
if (file != null)
{
var streamData = await file.OpenReadAsync();
var bytes = new byte[streamData.Size];
using (var dataReader = new DataReader(streamData))
{
await dataReader.LoadAsync((uint)streamData.Size);
dataReader.ReadBytes(bytes);
}
string fileToUpload = file.Path;
using (var fstream = await file.OpenReadAsync())
{
var streamContent = new System.Net.Http.ByteArrayContent(bytes);
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "files[]",
FileName = Path.GetFileName(fileToUpload),
};
content.Add(streamContent);
}
}
}
var response = await client.PostAsync(new Uri(UploadFilesURI, UriKind.Absolute), content);
var contentResponce = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<API.ResponceUploadFiles.RootObject>(contentResponce);
return result.cache;
}
catch { return ""; }
}

Categories

Resources