Has anyone attempted to do this? From what I understand Google doesn't provide a .NET client library for this (the only examples I found were in Python and PHP). The difficulty I'm having is that it seems to want a file upload and a JSON request body in the same request. Any info would be appreciated.
I was able to figure it out. In .NET (using HttpClient), you can use
using (MultipartFormDataContent content = new MultipartFormDataContent("----------" + DateTime.Now.ToString(CultureInfo.InvariantCulture)))
{
content.Add(new StringContent(JsonConvert.SerializeObject(uploadReferenceRequest), Encoding.UTF8, "application/json"));
StreamContent audioContent = new StreamContent(new MemoryStream(buffer));
audioContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Add(audioContent);
using (HttpResponseMessage response = await this.Client.PostAsync(url, content))
{
string responseContent = await response.Content.ReadAsStringAsync();
}
}
The key is to set the content type on each section of data, on the first is the "application/json" and the actual sound data is "application/octet-stream". Hope someone else finds this useful.
Related
Due to internal reason, I need to recode my servlet from Java to c#.
I am trying to upload a CSV file using the API PUT /marketing/contacts/imports with restsharp.
I cannot manage to send the file properly.
Code Snippet
Please fine below my java piece of code working:
File file = new File(CSV);
byte[] data;
try {
data = Files.readAllBytes(file.toPath());
HttpResponse<String> response2 = Unirest.put(URLSengrid)
.header(processSendgridHeader(headerFromSengrid).get(0), processSendgridHeader(headerFromSengrid).get(1))
//("x-amz-server-side-encryption", "aws:kms")
.body(data)
.asString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
And here the non working c# code:
byte[] file = System.IO.File.ReadAllBytes(testPath);
var clientSecondCall = new RestClient(URLSendgrid);
var requestSecondCall = new RestRequest(Method.PUT);
requestSecondCall.AddHeader("content -type", "application/json");
requestSecondCall.AddHeader("x-amz-server-side-encryption", "aws:kms");
requestSecondCall.AddParameter("application/json", "{"file_type":"csv","field_mappings":["e1_T","e2_T","_rf2_T","e4_T","e5_T","e12_T","e13_T","e14_T","e15_T","e16_T"]}", ParameterType.RequestBody);
requestSecondCall.AddFile("file", file, testPath);
I spent a long time looking for an answer without success. Any help would be appreciated
Technical details:
sendgrid-csharp version: 9.*
csharp version: v4.0.303190
I believe the problem is the way you send the file in your c# code.
The Java code is clearly using the Body of the request, while the c# code is using RestSharp.
Restsharp is sending files in as a Multipart form, which your server is probably not qualified to handle.
I would recommend using HttpClient object:
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage();
request.Method = HttpMethod.Put;
request.RequestUri = new Uri( "Your Url");
request.Content = new StringContent(File.ReadAllText(yourFilePath));
request.Headers.Add("your header name", "your header value");
var response = client.SendAsync(request).Result;
I'm trying to upload an .mp4 file to Giphy.com's API. It says to send the file over as 'Binary' and I think I'm confused as what exactly they mean by that. Here's the docs if you scroll to the bottom at "Upload Endpoint". https://developers.giphy.com/docs/
Here's what I have right now.
I've tried multiple versions of this (using StringContent, MultipartFormDataContent, ByteArrayContent, HttpMessages... etc) and always get a '400 - Bad Request - No Source Url' (which the docs say isn't required if you upload you're own) which makes me believe the content isn't being recognized.
public async Task<HttpResponseMessage> UploadVideoAsync(StorageFile file)
{
using (var stream = await file.OpenStreamForReadAsync())
{
byte[] bytes = new byte[stream.Length];
await stream.ReadAsync(bytes, 0, (int)stream.Length);
Dictionary<string, string> dic = new Dictionary<string, string>
{
{ "file", Encoding.ASCII.GetString(bytes) },
{ "api_key", api_key }
};
MultipartFormDataContent multipartContent = new MultipartFormDataContent();
multipartContent.Add(new ByteArrayContent(bytes));
var response = await httpClient.PostAsync($"v1/gifs?api_key={api_key}", multipartContent);
var stringResponse = await response.Content.ReadAsStringAsync();
return response;
}
}
It seems that your code doesn't match {api_key} properly. You don't use the "dic" variable anywhere. You can try with v1/gifs?api_key=YOUR_API_KEY&file= instead. Where YOUR_API_KEY should be replaced by your API key obtained from giphy.
always get a '400 - Bad Request - No Source Url' (which the docs say isn't required if you upload you're own) which makes me believe the content isn't being recognized.
You need to apply a name for the ByteArrayContent. The document has shown that Request Parameters contains 'file: string (binary) required if no source_image_url supplied'.
The code should like the following:
MultipartFormDataContent multipartContent = new MultipartFormDataContent();
multipartContent.Add(new ByteArrayContent(bytes),"file");
I am attempting to modify the metadata of a file that has just been uploaded.
using (HttpClient client = new HttpClient(new HttpClientHandler { Credentials = _authenticator.Credential }))
{
client.DefaultRequestHeaders.Add("X-HTTP-Method", "MERGE");
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-RequestDigest", _authenticator.Token);
client.BaseAddress = _authenticator.Endpoint;
client.DefaultRequestHeaders.Add("IF-MATCH", "*");
string cmd = String.Format("_api/web/lists/GetByTitle('Drop Off Library')/items({0})", file.Id);
string jsonString = JsonConvert.SerializeObject(file);
StringContent test = new StringContent(jsonString, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(cmd, test);
}
I successfully GET the file's metadata above, and store it in a SharePoint file model of my own creation. I modify one of the file's metadata fields, and then attempt to merge the deserialized object back in. This has been resulting in a 400 Bad Request error. Any ideas of why this might be happening?
The solution would be to replace the lines:
string jsonString = JsonConvert.SerializeObject(file);
StringContent test = new StringContent(jsonString, Encoding.UTF8, "application/json");
with
var test = new StringContent(JsonConvert.SerializeObject(payload));
test.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;odata=verbose");
since in your case the invalid Content-Type header is generated.
See JSON Light support in REST SharePoint API released for a list of supported formats.
If this is a duplicate of any existing question, please let me know which post has a similar situation.
I am trying to call a POST API, which actually works perfectly from REST clients like POSTMAN.
When I try to call that API from C# using HttpClient, it only works if I do not use any HTML content in the request body.
Here is my code:
HttpClient client = new HttpClient();
string baseUrl = channel.DomainName;
client.BaseAddress = new Uri(baseUrl);
client.DefaultRequestHeaders
.TryAddWithoutValidation(
"Content-Type",
"application/x-www-form-urlencoded;charset=utf-8");
const string serviceUrl = "/api/create";
var jsonString = CreateApiRequestBody(model, userId, false);
var uri = new Uri(baseUrl + serviceUrl);
try
{
HttpResponseMessage response = await client.PostAsync(uri.ToString(), new StringContent(jsonString, Encoding.UTF8, "application/json"));
if (response.IsSuccessStatusCode)
{
Stream receiveStream = response.Content.ReadAsStreamAsync().Result;
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
var str = readStream.ReadToEnd();
}
...
}
And my jsonString looks like:
{
\"user_id\":\"6\",
\"description\":\"<h2 style=\\\"font-style:italic;\\\"><u><font><font>Test Test Test </font></font></u></h2>\\n\\n<p style=\\\"font-style: italic;\\\">Hi it's a Test JOB</p>\\n\\n<p> </p>\"
}
When I use plain text in description tag, the API returns a valid response, but not with the HTML content in it.
I believe I might be missing some extra header or something else.
Any help will be greatly appreciated.
Have you tried using WebUtility.HtmlEncode() method?
Where you're setting the StringContent content, try using WebUtility.HtmlEncode(jsonString) to make it API-friendly.
Like this:
using System.Net;
HttpResponseMessage response =
await client.PostAsync(
uri.ToString(),
new StringContent(WebUtility.HtmlEncode(jsonString),
Encoding.UTF8,
"application/json"));
Don't forget to use System.Net
That will give you a safe (especially for APIs) HTML string to use in your request.
Hope this helps.
How would one post multiple binaries in a single http POST operation using C# httpclient? I can't seem to find information on how to deal with httpcontent in this way - just doing a postASync with stream data twice?
Dug around a bit more and experimented, and finally found what seems like a working solution. I tried this on a test server with some images on HD - both sent, both worked. With two stream examples.
var client = new HttpClient();
var stream3 = new FileStream("saved.jpg", FileMode.Open);
var stream2 = new FileStream("saved2.jpg", FileMode.Open);
var dic = new Dictionary<string, string>();
dic.Add("Test1", "This was the first test.");
var addy = "http://posttestserver.com/post.php";
using (var content = new MultipartFormDataContent())
{
content.Add(new StreamContent(stream2), "s1", "Saved1.jpg");
content.Add(new StreamContent(stream3), "s2", "Saved2.jpg");
var response = await client.PostAsync(addy, content);
response.EnsureSuccessStatusCode();
string finalresults = await response.Content.ReadAsStringAsync();
}
It will depend on the implementation of the API that you are sending your files to but typically if multiple files are sent in a single POST request then it is sent as multipart/form-data. Have a look at this post for sending multipart/form-data through HttpClient.