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

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

Related

How to Pass value along with file upload through webclient C# [duplicate]

How can I send a file and form data with the HttpClient?
I have two ways to send a file or form data. But I want to send both like an HTML form. How can I do that? Thanks.
This is my code:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
var client = new HttpClient();
var requestContent = new MultipartFormDataContent();
filename = openFileDialog1.FileName;
array = File.ReadAllBytes(filename);
var imageContent = new ByteArrayContent(array);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("audio/*");
requestContent.Add(imageContent, "audio", "audio.wav");
var values = new Dictionary<string, string>
{
{ "token", "b53b99534a137a71513548091271c44c" },
};
var content = new FormUrlEncodedContent(values);
requestContent.Add(content);
var response = await client.PostAsync("localhost", requestContent);
var responseString = await response.Content.ReadAsStringAsync();
txtbox.Text = responseString.ToString();
}
Here's code I'm using to post form information and a csv file
using (var httpClient = new HttpClient())
{
var surveyBytes = ConvertToByteArray(surveyResponse);
httpClient.DefaultRequestHeaders.Add("X-API-TOKEN", _apiToken);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var byteArrayContent = new ByteArrayContent(surveyBytes);
byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse("text/csv");
var response = await httpClient.PostAsync(_importUrl, new MultipartFormDataContent
{
{new StringContent(surveyId), "\"surveyId\""},
{byteArrayContent, "\"file\"", "\"feedback.csv\""}
});
return response;
}
This is for .net 4.5.
Note the \" in the MultipartFormDataContent. There is a bug in MultipartFormDataContent.
In 4.5.1 MultipartFormDataContent wraps the data with the correct quotes.
Update: This link to the bug no longer works since the have retired Microsoft Connect.
Here's code I'm using a method to send file and data from console to API
static async Task uploaddocAsync()
{
MultipartFormDataContent form = new MultipartFormDataContent();
Dictionary<string, string> parameters = new Dictionary<string, string>();
//parameters.Add("username", user.Username);
//parameters.Add("FullName", FullName);
HttpContent DictionaryItems = new FormUrlEncodedContent(parameters);
form.Add(DictionaryItems, "model");
try
{
var stream = new FileStream(#"D:\10th.jpeg", FileMode.Open);
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(#"http:\\xyz.in");
HttpContent content = new StringContent("");
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "uploadedFile1",
FileName = "uploadedFile1"
};
content = new StreamContent(stream);
form.Add(content, "uploadedFile1");
client.DefaultRequestHeaders.Add("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.dsfdsfdsfdsfsdfkhjhjkhjk.vD056hXETFMXYxOaLZRwV7Ny1vj-tZySAWq6oybBr2w");
var response = client.PostAsync(#"\api\UploadDocuments\", form).Result;
var k = response.Content.ReadAsStringAsync().Result;
}
catch (Exception ex)
{
}
}

How i can post file to web API from C#?

I need to post a file from asp application to an API
the file will be uploaded through <asp:FileUpload />
in the back end, i will receive the file and send it to Web API method
the web API method will contain the code
var root = HttpContext.Current.Server.MapPath("~/App_Data/Uploadfiles");
var provider = new MultipartFormDataStreamProvider(root);
var result = await Request.Content.ReadAsMultipartAsync(provider);
the asp page will has the code
using (System.IO.Stream fs = fuID.PostedFile.InputStream)
{
System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://localhost:5000/path"))
{
request.Headers.TryAddWithoutValidation("Accept", "application/json, text/plain, */*");
request.Headers.TryAddWithoutValidation("Authorization", "Bearer " + AppUserContext.Token);
request.Headers.TryAddWithoutValidation("x-language", "ar");
// Iam Not Sure of this line
request.Content = new StringContent("Content-Disposition:" + base64String, Encoding.UTF8, "multipart/form-data");
var response = httpClient.SendAsync(request).Result;
}
}
}
i need to know how i can send the file in the body of the request what to write in this line
request.Content = new StringContent("Content-Disposition:" + base64String, Encoding.UTF8, "multipart/form-data");
pf is the posted file
then use
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AppUserContext.Token);
client.DefaultRequestHeaders.Add("x-language", "ar");
using (var stream = pf.InputStream)
{
var content = new MultipartFormDataContent();
var file_content = new ByteArrayContent(new StreamContent(stream).ReadAsByteArrayAsync().Result);
file_content.Headers.ContentType = new MediaTypeHeaderValue(pf.ContentType);
file_content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = JsonConvert.SerializeObject(pf.FileName),
};
content.Add(file_content);
var url = "URL Here";
var response = client.PostAsync(url, content).Result;
response.EnsureSuccessStatusCode();
}
}

How to post form-data IFormFile with HttpClient?

I have backend endpoint Task<ActionResult> Post(IFormFile csvFile) and I need to call this endpoint from HttpClient. Currently I am getting Unsupported media type error.
Here is my code:
var filePath = Path.Combine("IntegrationTests", "file.csv");
var gg = File.ReadAllBytes(filePath);
var byteArrayContent = new ByteArrayContent(gg);
var postResponse = await _client.PostAsync("offers", new MultipartFormDataContent
{
{byteArrayContent }
});
You need to specify parameter name in MultipartFormDataContent collection matching action parameter name (csvFile) and a random file name
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(byteArrayContent, "csvFile", "filename");
var postResponse = await _client.PostAsync("offers", multipartContent);
or equivalent
var postResponse = await _client.PostAsync("offers", new MultipartFormDataContent {
{ byteArrayContent, "csvFile", "filename" }
});
Use this snippet:
const string url = "https://localhost:5001/api/Upload";
const string filePath = #"C:\Path\To\File.png";
using (var httpClient = new HttpClient())
{
using (var form = new MultipartFormDataContent())
{
using (var fs = File.OpenRead(filePath))
{
using (var streamContent = new StreamContent(fs))
{
using (var fileContent = new ByteArrayContent(await streamContent.ReadAsByteArrayAsync()))
{
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
// "file" parameter name should be the same as the server side input parameter name
form.Add(fileContent, "file", Path.GetFileName(filePath));
HttpResponseMessage response = await httpClient.PostAsync(url, form);
}
}
}
}
}
This worked for me as a generic
public static Task<HttpResponseMessage> PostFormDataAsync<T>(this HttpClient httpClient, string url, string token, T data)
{
var content = new MultipartFormDataContent();
foreach (var prop in data.GetType().GetProperties())
{
var value = prop.GetValue(data);
if (value is FormFile)
{
var file = value as FormFile;
content.Add(new StreamContent(file.OpenReadStream()), prop.Name, file.FileName);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = prop.Name, FileName = file.FileName };
}
else
{
content.Add(new StringContent(JsonConvert.SerializeObject(value)), prop.Name);
}
}
if (!string.IsNullOrWhiteSpace(token))
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
return httpClient.PostAsync(url, content);
}
Solved by using this code:
const string fileName = "csvFile.csv";
var filePath = Path.Combine("IntegrationTests", fileName);
var bytes = File.ReadAllBytes(filePath);
var form = new MultipartFormDataContent();
var content = new StreamContent(new MemoryStream(bytes));
form.Add(content, "csvFile");
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "csvFile",
FileName = fileName
};
content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "application/octet-stream; boundary=----WebKitFormBoundaryMRxYYlVt8KWT8TU3");
form.Add(content);
//Act
var postResponse = await _sellerClient.PostAsync("items/upload", form);
Post the attachment as an MultipartFormDataContent
var type = typeof(Startup);
var stream = type.Assembly.GetManifestResourceStream(type, "Resources.New.docx");
var fileContent = new StreamContent(stream);
var data = new MultipartFormDataContent
{
{ fileContent, "file", "New.docx" }
};
var response = await _client.PostAsync("upload", multipartContent);
Source: https://medium.com/#woeterman_94/c-webapi-upload-files-to-a-controller-e5ccf288b0ca
Please see the following working code with .NET 5.0 Environment.
You send the file as a byte[] and receive it as a IFormFile in the API.
//api controller receiver
[HttpPost("SendBackupFiles")]
public IActionResult SendBackupFiles(IFormFile file)
{
var filePath = Path.GetTempFileName();
using (var stream = System.IO.File.Create(filePath))
file.CopyToAsync(stream);
}
//client code sender example, not optimized lol.
const string filePath = #"C:\temp\hallo.csv";
using (var httpClient = new HttpClient())
{
var form = new MultipartFormDataContent();
byte[] fileData = File.ReadAllBytes(filePath);
ByteArrayContent byteContent = new ByteArrayContent(fileData);
byteContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
form.Add(byteContent, "file", Path.GetFileName(filePath));
var result = httpClient.PostAsync("http://localhost:5070/..yourControllerName.../SendBackupFiles", form).ConfigureAwait(false).GetAwaiter().GetResult().Content.ReadAsStringAsync().Result;
}

Uploaded file always with size zero

I am trying to upload the file to web API so I have the following code
public async Task<Token> upload(string fullMd5, IEnumerable<HttpPostedFileBase> files)
{
string uploadUrl = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
// Call CMS API
string jsonContent = string.Empty;
HttpClientHandler handler = new HttpClientHandler();
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
var filesData = new MultipartFormDataContent();
foreach (var item in files)
{
HttpContent filecontent = new StreamContent(item.InputStream);
filecontent.Headers.ContentType = new MediaTypeHeaderValue(item.ContentType);
filecontent.Headers.ContentLength += item.InputStream.Length;
filecontent.Headers.ContentDisposition = new ContentDispositionHeaderValue("multipart/form-data")
{
Name = "file",
FileName = item.FileName,
};
content.Add(filecontent);
}
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + userObj.access_token);
client.DefaultRequestHeaders.Add("Api-version", "2.4");
client.DefaultRequestHeaders.Add("CMSId", UserId);
var response = await client.PostAsync(uploadUrl, content);
jsonContent = await response.Content.ReadAsStringAsync();
}
}
var result = JsonConvert.DeserializeObject<Token>(jsonContent);
return result;
}
}
the API receive the files but corrupted with zero size , the API works well as I tested using postman , I tried to save the files before sending using SaveAs and it worked well any problem in how I send the file
Try using postAsync like this with these headers
using (var client = new HttpClient(handler) {BaseAddress = new Uri(_host)})
{
var requestContent = new MultipartFormDataContent();
var fileContent = new StreamContent(fileInfo.OpenRead());
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
Name = "\"file\"",
FileName = "\"" + fileInfo.Name + "\""
};
fileContent.Headers.ContentType =
MediaTypeHeaderValue.Parse(MimeMapping.GetMimeMapping(fileInfo.Name));
var folderContent = new StringContent(folderId.ToString(CultureInfo.InvariantCulture));
requestContent.Add(fileContent);
requestContent.Add(folderContent, "\"folderId\"");
var result = client.PostAsync("Company/AddFile", requestContent).Result;
}

Connecting to and uploading tracks with Soundcloud API using C# .NET

I'm trying to upload an audio track to the Soundcloud.com using C#.NET, but there aren't any resources for .NET anywhere. Could someone post a link or an example of how to upload an audio file to my Soundcloud.com account using .NET?
Thank you,
Arman
To upload an audio using soundcloud's REST API you need to take care of HTTP POST related issues (RFC 1867). In general, ASP.NET does not support sending of multiple files/values using POST, so I suggest you to use Krystalware library: http://aspnetupload.com/Upload-File-POST-HttpWebRequest-WebClient-RFC-1867.aspx
After that you need to send proper form fields to the https://api.soundcloud.com/tracks url:
Auth token (oauth_token)
Track Title (track[title])
The file (track[asset_data])
Sample code:
using Krystalware.UploadHelper;
...
System.Net.ServicePointManager.Expect100Continue = false;
var request = WebRequest.Create("https://api.soundcloud.com/tracks") as HttpWebRequest;
//some default headers
request.Accept = "*/*";
request.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "en-US,en;q=0.8,ru;q=0.6");
//file array
var files = new UploadFile[] {
new UploadFile(Server.MapPath("Downloads//0.mp3"), "track[asset_data]", "application/octet-stream")
};
//other form data
var form = new NameValueCollection();
form.Add("track[title]", "Some title");
form.Add("track[sharing]", "private");
form.Add("oauth_token", this.Token);
form.Add("format", "json");
form.Add("Filename", "0.mp3");
form.Add("Upload", "Submit Query");
try
{
using (var response = HttpUploadHelper.Upload(request, files, form))
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
lblInfo.Text = reader.ReadToEnd();
}
}
}
catch (Exception ex)
{
lblInfo.Text = ex.ToString();
}
The example code allows you to upload an audio file from the server (notice the Server.MapPath method to form path to the file) and to get a response in json format (reader.ReadToEnd)
Here is a code snippet to upload track via the SoundCloud API =>
using (HttpClient httpClient = new HttpClient()) {
httpClient.DefaultRequestHeaders.ConnectionClose = true;
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MySoundCloudClient", "1.0"));
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OAuth", "MY_AUTH_TOKEN");
ByteArrayContent titleContent = new ByteArrayContent(Encoding.UTF8.GetBytes("my title"));
ByteArrayContent sharingContent = new ByteArrayContent(Encoding.UTF8.GetBytes("private"));
ByteArrayContent byteArrayContent = new ByteArrayContent(File.ReadAllBytes("MYFILENAME"));
byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(titleContent, "track[title]");
content.Add(sharingContent, "track[sharing]");
content.Add(byteArrayContent, "track[asset_data]", "MYFILENAME");
HttpResponseMessage message = await httpClient.PostAsync(new Uri("https://api.soundcloud.com/tracks"), content);
if (message.IsSuccessStatusCode) {
...
}
Here another way to get non expiring token and upload track to SoundCloud using C#:
public class SoundCloudService : ISoundPlatformService
{
public SoundCloudService()
{
Errors=new List<string>();
}
private const string baseAddress = "https://api.soundcloud.com/";
public IList<string> Errors { get; set; }
public async Task<string> GetNonExpiringTokenAsync()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseAddress);
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("client_id","xxxxxx"),
new KeyValuePair<string, string>("client_secret","xxxxxx"),
new KeyValuePair<string, string>("grant_type","password"),
new KeyValuePair<string, string>("username","xx#xx.com"),
new KeyValuePair<string, string>("password","xxxxx"),
new KeyValuePair<string, string>("scope","non-expiring")
});
var response = await client.PostAsync("oauth2/token", content);
if (response.StatusCode == HttpStatusCode.OK)
{
dynamic data = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
return data.access_token;
}
Errors.Add(string.Format("{0} {1}", response.StatusCode, response.ReasonPhrase));
return null;
}
}
public async Task UploadTrackAsync(string filePath)
{
using (var client = new HttpClient())
{
client.BaseAddress=new Uri(baseAddress);
var form = new MultipartFormDataContent(Guid.NewGuid().ToString());
var contentTitle = new StringContent("Test");
contentTitle.Headers.ContentType = null;
form.Add(contentTitle, "track[title]");
var contentSharing = new StringContent("private");
contentSharing.Headers.ContentType = null;
form.Add(contentSharing, "track[sharing]");
var contentToken = new StringContent("xxxxx");
contentToken.Headers.ContentType = null;
form.Add(contentToken, "[oauth_token]");
var contentFormat = new StringContent("json");
contentFormat.Headers.ContentType = null;
form.Add(contentFormat, "[format]");
var contentFilename = new StringContent("test.mp3");
contentFilename.Headers.ContentType = null;
form.Add(contentFilename, "[Filename]");
var contentUpload = new StringContent("Submit Query");
contentUpload.Headers.ContentType = null;
form.Add(contentUpload, "[Upload]");
var contentTags = new StringContent("Test");
contentTags.Headers.ContentType = null;
form.Add(contentTags, "track[tag_list]");
var bytes = File.ReadAllBytes(filePath);
var contentFile = new ByteArrayContent(bytes, 0, bytes.Count());
contentFile.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
form.Add(contentFile, "track[asset_data]", "test.mp3");
var response = await client.PostAsync("tracks", form);
}
}
}

Categories

Resources