Post string and bytearray to server - c#

I have done POSTING and GETing from server using string post data, but now i have the next WebService:
submitFeedback(String token, String subject, String body, byte[] photo, byte[] video);
private void PostFeedbackData()
{
if (GS.online != true)
{
MessageBox.Show(GS.translations["ErrorMsg0"]);
}
else
{
HttpWebRequest request = HttpWebRequest.CreateHttp("https://****/feedback");
request.Method = "POST";
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
}
}
void GetRequestStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
// End the stream request operation
Stream postStream = myRequest.EndGetRequestStream(callbackResult);
// Create the post data
string postData = "";
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
postData = "{\"jsonrpc\": \"2.0\", \"method\": \"getUserSchedule\", \"params\":[" + "\"" + (App.Current as App).UserToken + "\",\"" + FeedbackTitle.Text + "\",\"" + FeedbackContent.Text + "\",\"" + imageBytes + "\"], \"id\": 1}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Start the web request
myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), myRequest);
});
}
Look at post data - it is a string, i can't place there imageBytes array. How to do it?

Is there any reason for using HttpWebRequest ?
I am asking that because i think that the correct way of sending files to a service is by multipartform data. With HttpWebRequest you have to manually implement that.
Here is an example that is using Microsoft's HttpClient that might work for you:
public async Task<string> submitFeedback(String token, String subject, String body, byte[] photo, byte[] video) {
var client = new HttpClient();
var content = new MultipartFormDataContent();
// Some APIs do not support quotes in boundary field
foreach (var param in content.Headers.ContentType.Parameters.Where(param => param.Name.Equals("boundary")))
param.Value = param.Value.Replace("\"", String.Empty);
var tok = new StringContent(token);
content.Add(tok, "\"token\"");
var sub = new StringContent(subject);
content.Add(tok, "\"subject\"");
// Add the Photo
var photoContent = new StreamContent(new MemoryStream(photo));
photoContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"photo\"",
FileName = "\"photoname.jpg\""
};
photoContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(photoContent);
// Add the video
var videoContent = new StreamContent(new MemoryStream(video));
videoContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"video\"",
FileName = "\"videoname.jpg\""
};
videoContent.Headers.ContentType = MediaTypeHeaderValue.Parse("video/mp4");
content.Add(videoContent);
HttpResponseMessage resp;
try {
resp = await client.PostAsync("SERVER_URL_GOES_HERE", content);
}
catch (Exception e)
{
return "EXCEPTION ERROR";
}
if (resp.StatusCode != HttpStatusCode.OK)
{
return resp.StatusCode.ToString();
}
var reponse = await resp.Content.ReadAsStringAsync();
return reponse;
}
Change accordingly.
Note: HttpClient is also using HttpWebRequest under the hood.
Also I don't think its a good idea to have the UI thread making the request. That makes no sense since you are blocking the interface and making the async theory useless.

Related

c# to get oauth2 token but get error (Remote server returns 400 Bad Request)

I am trying to use this C# to get oauth token from a website. But the below codes return '404 Bad Request' error. Is there anything wrong in my code? The website engineer says there should be a JSON file returned to show error details. How do I get that JSON file? What I can see is just 1 line error message in VS2012.
private void Button_Click_1(object sender, RoutedEventArgs e)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://xxxx.com/api/oauth/token");
webRequest.Method = "POST";
webRequest.AllowAutoRedirect = true;
//write the data to post request
String postData = "client_id=abc&client_secret=xxx&grant_type=client_credentials";
byte[] buffer = Encoding.Default.GetBytes(postData);
if (buffer != null)
{
webRequest.ContentLength = buffer.Length;
webRequest.GetRequestStream().Write(buffer, 0, buffer.Length);
}
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string strResponse = reader.ReadToEnd();
I used Postman to send a request and I can get the token in its response. How should I modify my C# codes to get the token?
Can you try like this
public (string, string, string, string) GetOAuth(string CliendId, string ClientSecret, string OAuthURl)
{
using (var httpClient = new HttpClient())
{
var creds = $"client_id={CliendId}&client_secret={ClientSecret}&grant_type=client_credentials";
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var content = new StringContent(creds, Encoding.UTF8, "application/x-www-form-urlencoded");
var response = httpClient.PostAsync(OAuthURl, content).Result;
var jsonContent = response.Content.ReadAsStringAsync().Result;
var tokenObj = JsonConvert.DeserializeObject<dynamic>(jsonContent);
var access_token = tokenObj?.access_token;
var token_type = tokenObj?.token_type;
var expires_in = tokenObj?.expires_in;
var scope = tokenObj?.scope;
return (access_token, token_type, expires_in, scope);
}
}
private void HowTOUse()
{
string access_token, token_type, expires_in, scope;
(access_token, token_type, expires_in, scope) = GetOAuth("client_id", "client_secret", "oauthurl");
}
Try using like the below code hope this code will solve the problem
private void Button_Click_1(object sender, RoutedEventArgs e)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://xxxx.com/api/oauth/token");
webRequest.Method = "POST";
webRequest.AllowAutoRedirect = true;
//write the data to post request
String postData =
"client_id=abc&client_secret=xxx&grant_type=client_credentials";
//byte[] buffer = Encoding.Default.GetBytes(postData);
//add these lines
byte[] buffer = System.Text.Encoding.ASCII.GetBytes(postData);
if (buffer != null)
{
webRequest.ContentLength = buffer.Length;
webRequest.GetRequestStream().Write(buffer, 0, buffer.Length);
}
try
{
using (HttpWebResponse response =
(HttpWebResponse)webRequest.GetResponse())
{
using (Stream dataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(dataStream);
string strResponse = reader.ReadToEnd();
TokenModel dt = JsonConvert.DeserializeObject<TokenModel>
(strResponse);
token = dt.accessToken;
//Assign json Token values from strResponse to model tok_val
tok_val.accessToken = dt.accessToken;
tok_val.expires_in = dt.expires_in;
tok_val.RefreshToken = dt.RefreshToken;
tok_val.tokenType = dt.tokenType;
}
}
}
catch (WebException wex)
{
error = "Request Issue: " + wex.Message;
}
catch (Exception ex)
{
error = "Issue: " + ex.Message;
}

Xamarin Forms Json Service Insert Data

I want to add a record to the json service in my application. How can I do this via Service Url. Here is my code.
CustomerModel customer = new CustomerModel();
customer.Name = entryCompanyName.Text;
customer.Title = entryCompanyTitle.Text;
customer.PhoneNumber = entryTelephone.Text;
customer.FaxNumber = entryFax.Text;
customer.Email = entryEmail.Text;
customer.CityId = 6444;
string json = JsonConvert.SerializeObject(customer);
string sContentType = "application/json";
string path = "service url";
HttpClient Client = new HttpClient();
var task = Client.PostAsync(path, new StringContent(json.ToString(), Encoding.UTF8, sContentType));
I'm trying M. Wiśnicki's solution, but I took this error
I did not get an error when I added System.net :( Where do i make mistakes?
This worked for me
public static async Task<string> PostEntityToApi<T>(string yourMethodUrl, T yourModel)
{
try
{
if (_httpClient == null)
{
_httpClient = new HttpClient { BaseAddress = new Uri(yourWebSiteUrl) };
}
var stringContentInput = new StringContent(JsonConvert.SerializeObject(dto), Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(new Uri(yourWebSiteUrl. + apiUrl), stringContentInput);
if (!response.IsSuccessStatusCode)
{
throw new Exception(response.StatusCode.ToString());
}
var stringAsync = await response.Content.ReadAsStringAsync();
LoggingManager.Error("Received error response: " + stringAsync);
return stringAsync;
}
catch (Exception exception)
{
return null;
}
}
You can use WebRequest, this sample working for me, i use it in my app.
This is System.Net.WebRequest class, here you find doc.
public async Task<string> PostSample(object data, string uri)
{
// Create an HTTP web request using the URL:
var request = (HttpWebRequest) WebRequest.Create(new Uri(uri));
request.ContentType = "application/json";
request.Method = "POST";
var itemToSend = JsonConvert.SerializeObject(data);
using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
streamWriter.Write(itemToSend);
streamWriter.Flush();
streamWriter.Dispose();
}
// Send the request to the server and wait for the response:
using (var response = await request.GetResponseAsync())
{
// Get a stream representation of the HTTP web response:
using (var stream = response.GetResponseStream())
{
var reader = new StreamReader(stream);
var message = JsonConvert.DeserializeObject<string>(reader.ReadToEnd());
return message;
}
}
}

Saving a token to be reused after a loop

I am working on a project where I can only return 30 results at a time from a server. I am using a loop in my program to change a parameter of the connection and return the next set after each loop by using the GetWorkers() command below.
I need to use a token to get the JObject.Parse(serverResponse). I want to be able to save the Token upon each loop to reuse it since it times out after 1 hour.
I am not sure what the best way to save the token is upon every loop. Currently it takes 30 sec to 1 minute to execute this entire process, and I would like it to be shorter anywhere I can manage to avoid any timeouts.
private ADPAccessToken GetAccessToken()
{
//var session = HttpContext.Current.Session;
////var session = Request.Properties["System.Web.HttpContex"] as HttpContextWrapper;
ADPAccessToken token = null;
//if (session["Token"] != null)
//{
// token = session["Token"] as ADPAccessToken;
// if (DateTime.Compare(DateTime.Now, token.ExpiresOn.Value) > 0)
// token = null;
//}
if (token == null)
{
//string formData = string.Concat("grant_type=client_credentials&scope=", HttpUtility.UrlEncode(accessScope));
string formData = string.Concat("grant_type=client_credentials");
var usrpwd = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Concat(NetworkUserName, ":", NetworkUserPassword)));
byte[] data = Encoding.ASCII.GetBytes(formData);
var result = postToADPServer(ADPAuthenticationURL, data, "Basic " + usrpwd);
if (!string.IsNullOrEmpty(result))
{
token = JsonConvert.DeserializeObject<ADPAccessToken>(result);
//session["Token"] = token;
}
}
return token;
}
public JObject GetWorkers()
{
return GetData(getWorkerURL);
}
private JObject GetData(string url)
{
ADPAccessToken token = GetAccessToken();
HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
var usrpwd = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(token.TokenType + " " + token.AccessToken));
var serverResponse = postToADPServer(url, null, token.TokenType + " " + token.AccessToken, "application/json");
return JObject.Parse(serverResponse);
}
private string postToADPServer(string url, byte[] postData, string authorization, string contentType = null)
{
HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
X509Certificate2 certificate = new X509Certificate2(");
myHttpWebRequest.ClientCertificates.Add(certificate);
myHttpWebRequest.Headers.Add(HttpRequestHeader.Authorization, authorization);
if (postData != null)
{
if (!string.IsNullOrEmpty(contentType))
myHttpWebRequest.ContentType = contentType;
else
myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
myHttpWebRequest.Method = "POST";
myHttpWebRequest.ContentLength = postData.Length;
Stream requestStream = myHttpWebRequest.GetRequestStream();
requestStream.Write(postData, 0, postData.Length);
requestStream.Close();
}
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
Stream responseStream = myHttpWebResponse.GetResponseStream();
StreamReader myStreamReader = new StreamReader(responseStream, Encoding.Default);
string pageContent = myStreamReader.ReadToEnd();
myStreamReader.Close();
responseStream.Close();
myHttpWebResponse.Close();
return pageContent;
}

How to upload file to server with HTTP POST multipart/form-data?

I am developing Windows Phone 8 app. I want to upload SQLite database via PHP web service using HTTP POST request with MIME type multipart/form-data & a string data called "userid=SOME_ID".
I don't want to use 3rd party libs like HttpClient, RestSharp or MyToolkit. I tried the below code but it doesn't upload the file & also doesn't give me any errors. It's working fine in Android, PHP, etc so there's no issue in web service. Below is my given code (for WP8). what's wrong with it?
I've googled and I'm not getting specific for WP8
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(DBNAME);
//Below line gives me file with 0 bytes, why? Should I use
//IsolatedStorageFile instead of StorageFile
//var file = await ApplicationData.Current.LocalFolder.GetFileAsync(DBNAME);
byte[] fileBytes = null;
using (var stream = await file.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (var reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
//var res = await HttpPost(Util.UPLOAD_BACKUP, fileBytes);
HttpPost(fileBytes);
}
private void HttpPost(byte[] file_bytes)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.myserver.com/upload.php");
httpWebRequest.ContentType = "multipart/form-data";
httpWebRequest.Method = "POST";
var asyncResult = httpWebRequest.BeginGetRequestStream((ar) => { GetRequestStreamCallback(ar, file_bytes); }, httpWebRequest);
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult, byte[] postData)
{
//DON'T KNOW HOW TO PASS "userid=some_user_id"
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
postStream.Write(postData, 0, postData.Length);
postStream.Close();
var asyncResult = request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
streamResponse.Close();
streamRead.Close();
response.Close();
}
I also tried to solve my problem in Windows 8 but it's also not working.
public async Task Upload(byte[] fileBytes)
{
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture)))
{
content.Add(new StreamContent(new MemoryStream(fileBytes)));
//Not sure below line is true or not
content.Add(new StringContent("userid=farhanW8"));
using (var message = await client.PostAsync("http://www.myserver.com/upload.php", content))
{
var input = await message.Content.ReadAsStringAsync();
}
}
}
}
Basic implementation using MultipartFormDataContent :-
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
form.Add(new StringContent(username), "username");
form.Add(new StringContent(useremail), "email");
form.Add(new StringContent(password), "password");
form.Add(new ByteArrayContent(file_bytes, 0, file_bytes.Length), "profile_pic", "hello1.jpg");
HttpResponseMessage response = await httpClient.PostAsync("PostUrl", form);
response.EnsureSuccessStatusCode();
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;
Here's my final working code. My web service needed one file (POST parameter name was "file") & a string value (POST parameter name was "userid").
/// <summary>
/// Occurs when upload backup application bar button is clicked. Author : Farhan Ghumra
/// </summary>
private async void btnUploadBackup_Click(object sender, EventArgs e)
{
var dbFile = await ApplicationData.Current.LocalFolder.GetFileAsync(Util.DBNAME);
var fileBytes = await GetBytesAsync(dbFile);
var Params = new Dictionary<string, string> { { "userid", "9" } };
UploadFilesToServer(new Uri(Util.UPLOAD_BACKUP), Params, Path.GetFileName(dbFile.Path), "application/octet-stream", fileBytes);
}
/// <summary>
/// Creates HTTP POST request & uploads database to server. Author : Farhan Ghumra
/// </summary>
private void UploadFilesToServer(Uri uri, Dictionary<string, string> data, string fileName, string fileContentType, byte[] fileData)
{
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest.Method = "POST";
httpWebRequest.BeginGetRequestStream((result) =>
{
try
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
using (Stream requestStream = request.EndGetRequestStream(result))
{
WriteMultipartForm(requestStream, boundary, data, fileName, fileContentType, fileData);
}
request.BeginGetResponse(a =>
{
try
{
var response = request.EndGetResponse(a);
var responseStream = response.GetResponseStream();
using (var sr = new StreamReader(responseStream))
{
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
{
string responseString = streamReader.ReadToEnd();
//responseString is depend upon your web service.
if (responseString == "Success")
{
MessageBox.Show("Backup stored successfully on server.");
}
else
{
MessageBox.Show("Error occurred while uploading backup on server.");
}
}
}
}
catch (Exception)
{
}
}, null);
}
catch (Exception)
{
}
}, httpWebRequest);
}
/// <summary>
/// Writes multi part HTTP POST request. Author : Farhan Ghumra
/// </summary>
private void WriteMultipartForm(Stream s, string boundary, Dictionary<string, string> data, string fileName, string fileContentType, byte[] fileData)
{
/// The first boundary
byte[] boundarybytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
/// the last boundary.
byte[] trailer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
/// the form data, properly formatted
string formdataTemplate = "Content-Dis-data; name=\"{0}\"\r\n\r\n{1}";
/// the form-data file upload, properly formatted
string fileheaderTemplate = "Content-Dis-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n";
/// Added to track if we need a CRLF or not.
bool bNeedsCRLF = false;
if (data != null)
{
foreach (string key in data.Keys)
{
/// if we need to drop a CRLF, do that.
if (bNeedsCRLF)
WriteToStream(s, "\r\n");
/// Write the boundary.
WriteToStream(s, boundarybytes);
/// Write the key.
WriteToStream(s, string.Format(formdataTemplate, key, data[key]));
bNeedsCRLF = true;
}
}
/// If we don't have keys, we don't need a crlf.
if (bNeedsCRLF)
WriteToStream(s, "\r\n");
WriteToStream(s, boundarybytes);
WriteToStream(s, string.Format(fileheaderTemplate, "file", fileName, fileContentType));
/// Write the file data to the stream.
WriteToStream(s, fileData);
WriteToStream(s, trailer);
}
/// <summary>
/// Writes string to stream. Author : Farhan Ghumra
/// </summary>
private void WriteToStream(Stream s, string txt)
{
byte[] bytes = Encoding.UTF8.GetBytes(txt);
s.Write(bytes, 0, bytes.Length);
}
/// <summary>
/// Writes byte array to stream. Author : Farhan Ghumra
/// </summary>
private void WriteToStream(Stream s, byte[] bytes)
{
s.Write(bytes, 0, bytes.Length);
}
/// <summary>
/// Returns byte array from StorageFile. Author : Farhan Ghumra
/// </summary>
private async Task<byte[]> GetBytesAsync(StorageFile file)
{
byte[] fileBytes = null;
using (var stream = await file.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (var reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
return fileBytes;
}
I am very much thankful to Darin Rousseau for helping me.
This simplistic version also works.
public void UploadMultipart(byte[] file, string filename, string contentType, string url)
{
var webClient = new WebClient();
string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
webClient.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
var fileData = webClient.Encoding.GetString(file);
var package = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n{3}\r\n--{0}--\r\n", boundary, filename, contentType, fileData);
var nfile = webClient.Encoding.GetBytes(package);
byte[] resp = webClient.UploadData(url, "POST", nfile);
}
Add any extra required headers if needed.
I've been playing around a little bit and came up with a simplified, more generic solution:
private static string sendHttpRequest(string url, NameValueCollection values, NameValueCollection files = null)
{
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
// The first boundary
byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
// The last boundary
byte[] trailer = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
// The first time it itereates, we need to make sure it doesn't put too many new paragraphs down or it completely messes up poor webbrick
byte[] boundaryBytesF = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
// Create the request and set parameters
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Get request stream
Stream requestStream = request.GetRequestStream();
foreach (string key in values.Keys)
{
// Write item to stream
byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}", key, values[key]));
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
requestStream.Write(formItemBytes, 0, formItemBytes.Length);
}
if (files != null)
{
foreach(string key in files.Keys)
{
if(File.Exists(files[key]))
{
int bytesRead = 0;
byte[] buffer = new byte[2048];
byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n", key, files[key]));
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
requestStream.Write(formItemBytes, 0, formItemBytes.Length);
using (FileStream fileStream = new FileStream(files[key], FileMode.Open, FileAccess.Read))
{
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
// Write file content to stream, byte by byte
requestStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
}
}
}
}
// Write trailer and close stream
requestStream.Write(trailer, 0, trailer.Length);
requestStream.Close();
using (StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream()))
{
return reader.ReadToEnd();
};
}
You can use it like this:
string fileLocation = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Path.DirectorySeparatorChar + "somefile.jpg";
NameValueCollection values = new NameValueCollection();
NameValueCollection files = new NameValueCollection();
values.Add("firstName", "Alan");
files.Add("profilePicture", fileLocation);
sendHttpRequest("http://example.com/handler.php", values, files);
And in the PHP script you could handle data like this:
echo $_POST['firstName'];
$name = $_POST['firstName'];
$image = $_FILES['profilePicture'];
$ds = DIRECTORY_SEPARATOR;
move_uploaded_file($image['tmp_name'], realpath(dirname(__FILE__)) . $ds . "uploads" . $ds . $image['name']);
You can use this class:
using System.Collections.Specialized;
class Post_File
{
public static void HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc)
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
byte[] boundarybytesF = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n"); // the first time it itereates, you need to make sure it doesn't put too many new paragraphs down or it completely messes up poor webbrick.
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
wr.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
var nvc2 = new NameValueCollection();
nvc2.Add("Accepts-Language", "en-us,en;q=0.5");
wr.Headers.Add(nvc2);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
Stream rs = wr.GetRequestStream();
bool firstLoop = true;
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
foreach (string key in nvc.Keys)
{
if (firstLoop)
{
rs.Write(boundarybytesF, 0, boundarybytesF.Length);
firstLoop = false;
}
else
{
rs.Write(boundarybytes, 0, boundarybytes.Length);
}
string formitem = string.Format(formdataTemplate, key, nvc[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
rs.Write(formitembytes, 0, formitembytes.Length);
}
rs.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string header = string.Format(headerTemplate, paramName, new FileInfo(file).Name, contentType);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, bytesRead);
}
fileStream.Close();
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
rs.Write(trailer, 0, trailer.Length);
rs.Close();
WebResponse wresp = null;
try
{
wresp = wr.GetResponse();
Stream stream2 = wresp.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
}
catch (Exception ex)
{
if (wresp != null)
{
wresp.Close();
wresp = null;
}
}
finally
{
wr = null;
}
}
}
use it:
NameValueCollection nvc = new NameValueCollection();
//nvc.Add("id", "TTR");
nvc.Add("table_name", "uploadfile");
nvc.Add("commit", "uploadfile");
Post_File.HttpUploadFile("http://example/upload_file.php", #"C:\user\yourfile.docx", "uploadfile", "application/vnd.ms-excel", nvc);
example server upload_file.php:
m('File upload '.(#copy($_FILES['uploadfile']['tmp_name'],getcwd().'\\'.'/'.$_FILES['uploadfile']['name']) ? 'success' : 'failed'));
function m($msg) {
echo '<div style="background:#f1f1f1;border:1px solid #ddd;padding:15px;font:14px;text-align:center;font-weight:bold;">';
echo $msg;
echo '</div>';
}
Here is what worked for me while sending the file as mult-form data:
public T HttpPostMultiPartFileStream<T>(string requestURL, string filePath, string fileName)
{
string content = null;
using (MultipartFormDataContent form = new MultipartFormDataContent())
{
StreamContent streamContent;
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
streamContent = new StreamContent(fileStream);
streamContent.Headers.Add("Content-Type", "application/octet-stream");
streamContent.Headers.Add("Content-Disposition", string.Format("form-data; name=\"file\"; filename=\"{0}\"", fileName));
form.Add(streamContent, "file", fileName);
using (HttpClient client = GetAuthenticatedHttpClient())
{
HttpResponseMessage response = client.PostAsync(requestURL, form).GetAwaiter().GetResult();
content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
try
{
return JsonConvert.DeserializeObject<T>(content);
}
catch (Exception ex)
{
// Log the exception
}
return default(T);
}
}
}
}
GetAuthenticatedHttpClient used above can be:
private HttpClient GetAuthenticatedHttpClient()
{
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(<yourBaseURL>));
httpClient.DefaultRequestHeaders.Add("Token, <yourToken>);
return httpClient;
}
I know this is and old thread, but I was fighting with this and I would like to share my solution.
This solution works with HttpClient and MultipartFormDataContent, from System.Net.Http. You can release it with .NET Core 1.0 or higher, or .NET Framework 4.5 or higher.
As a quick summary, it's an asynchronous method that receives as parameters the URL in which you want to perform the POST, a key/value collection for sending strings, and a key/value collection for sending files.
private static async Task<HttpResponseMessage> Post(string url, NameValueCollection strings, NameValueCollection files)
{
var formContent = new MultipartFormDataContent(/* If you need a boundary, you can define it here */);
// Strings
foreach (string key in strings.Keys)
{
string inputName = key;
string content = strings[key];
formContent.Add(new StringContent(content), inputName);
}
// Files
foreach (string key in files.Keys)
{
string inputName = key;
string fullPathToFile = files[key];
FileStream fileStream = File.OpenRead(fullPathToFile);
var streamContent = new StreamContent(fileStream);
var fileContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
formContent.Add(fileContent, inputName, Path.GetFileName(fullPathToFile));
}
var myHttpClient = new HttpClient();
var response = await myHttpClient.PostAsync(url, formContent);
//string stringContent = await response.Content.ReadAsStringAsync(); // If you need to read the content
return response;
}
You can prepare your POST like this (you can add so many strings and files as you need):
string url = #"http://yoursite.com/upload.php"
NameValueCollection strings = new NameValueCollection();
strings.Add("stringInputName1", "The content for input 1");
strings.Add("stringInputNameN", "The content for input N");
NameValueCollection files = new NameValueCollection();
files.Add("fileInputName1", #"FullPathToFile1"); // Path + filename
files.Add("fileInputNameN", #"FullPathToFileN");
And finally, call the method like this:
var result = Post(url, strings, files).GetAwaiter().GetResult();
If you want, you can check your status code, and show the reason as below:
if (result.StatusCode == HttpStatusCode.OK)
{
// Logic if all was OK
}
else
{
// You can show a message like this:
Console.WriteLine(string.Format("Error. StatusCode: {0} | ReasonPhrase: {1}", result.StatusCode, result.ReasonPhrase));
}
And if someone need it, here I let a small example of how to receive store a file with PHP (at the other side of our .Net app):
<?php
if (isset($_FILES['fileInputName1']) && $_FILES['fileInputName1']['error'] === UPLOAD_ERR_OK)
{
$fileTmpPath = $_FILES['fileInputName1']['tmp_name'];
$fileName = $_FILES['fileInputName1']['name'];
move_uploaded_file($fileTmpPath, '/the/final/path/you/want/' . $fileName);
}
I hope you find it useful, I am attentive to your questions.
The below code reads a file, converts it to a byte array and then makes a request to the server.
public void PostImage()
{
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
byte[] imagebytearraystring = ImageFileToByteArray(#"C:\Users\Downloads\icon.png");
form.Add(new ByteArrayContent(imagebytearraystring, 0, imagebytearraystring.Count()), "profile_pic", "hello1.jpg");
HttpResponseMessage response = httpClient.PostAsync("your url", form).Result;
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;
}
private byte[] ImageFileToByteArray(string fullFilePath)
{
FileStream fs = File.OpenRead(fullFilePath);
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
fs.Close();
return bytes;
}
hi guys after one day searching on web finally i solve problem with below source code
hope to help you
public UploadResult UploadFile(string fileAddress)
{
HttpClient client = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent content = new StringContent("fileToUpload");
form.Add(content, "fileToUpload");
var stream = new FileStream(fileAddress, FileMode.Open);
content = new StreamContent(stream);
var fileName =
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "name",
FileName = Path.GetFileName(fileAddress),
};
form.Add(content);
HttpResponseMessage response = null;
var url = new Uri("http://192.168.10.236:2000/api/Upload2");
response = (client.PostAsync(url, form)).Result;
}
Here is multipart data post with basic authentication C#
public string UploadFilesToRemoteUrl(string url)
{
try
{
Dictionary<string, object> formFields = new Dictionary<string, object>();
formFields.Add("requestid", "{\"id\":\"idvalue\"}");
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" + boundary;
// basic authentication.
var username = "userid";
var password = "password";
string credidentials = username + ":" + password;
var authorization = Convert.ToBase64String(Encoding.Default.GetBytes(credidentials));
request.Headers["Authorization"] = "Basic " + authorization;
request.Method = "POST";
request.KeepAlive = true;
Stream memStream = new System.IO.MemoryStream();
WriteFormData(formFields, memStream, boundary);
FileInfo fileToUpload = new FileInfo(#"filelocation with name");
string fileFormKey = "file";
if (fileToUpload != null)
{
WritefileToUpload(fileToUpload, memStream, boundary, fileFormKey);
}
request.ContentLength = memStream.Length;
using (Stream requestStream = request.GetRequestStream())
{
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
}
using (var response = request.GetResponse())
{
Stream responseSReam = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseSReam);
return streamReader.ReadToEnd();
}
}
catch (WebException ex)
{
using (WebResponse response = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
using (var streamReader = new StreamReader(response.GetResponseStream()))
return streamReader.ReadToEnd();
}
}
}
// write form id.
public static void WriteFormData(Dictionary<string, object> dictionary, Stream stream, string mimeBoundary)
{
string formdataTemplate = "\r\n--" + mimeBoundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
if (dictionary != null)
{
foreach (string key in dictionary.Keys)
{
string formitem = string.Format(formdataTemplate, key, dictionary[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
stream.Write(formitembytes, 0, formitembytes.Length);
}
}
}
// write file.
public static void WritefileToUpload(FileInfo file, Stream stream, string mimeBoundary, string formkey)
{
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + mimeBoundary + "\r\n");
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + mimeBoundary + "--");
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
stream.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, formkey, file.Name);
var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
stream.Write(headerbytes, 0, headerbytes.Length);
using (var fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[1024];
var bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
stream.Write(buffer, 0, bytesRead);
}
}
stream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
}
For people searching for 403 forbidden issue while trying to upload in multipart form the below might help as there is a case depending on the server configuration that you will get MULTIPART_STRICT_ERROR "!#eq 0" due to incorrect MultipartFormDataContent headers.
Please note that both imagetag/filename variables include quotations (\")
eg filename="\"myfile.png\"" .
MultipartFormDataContent form = new MultipartFormDataContent();
ByteArrayContent imageContent = new ByteArrayContent(fileBytes, 0, fileBytes.Length);
imageContent.Headers.TryAddWithoutValidation("Content-Disposition", "form-data; name="+imagetag+"; filename="+filename);
imageContent.Headers.TryAddWithoutValidation("Content-Type", "image / png");
form.Add(imageContent, imagetag, filename);
I was also wanted to upload stuff to a Server and it was a Spring application i finally discovered that I needed to acctually set an content type for it to interpret it as a file. Just like this:
...
MultipartFormDataContent form = new MultipartFormDataContent();
var fileStream = new FileStream(uniqueTempPathInProject, FileMode.Open);
var streamContent = new StreamContent(fileStream);
streamContent.Headers.ContentType=new MediaTypeHeaderValue("application/zip");
form.Add(streamContent, "file",fileName);
...
I know this is an old post, but after spending an entire afternoon trying, I have to share what worked for me. My solution is for a Xamarin application but the code should still work as long as it is C#:
The issue I had is that I wanted to use the same end-point and payload as my Angular app. (Code Below).
public class ApiService<T> where T : class
{
private string _webServiceUrl = Settings.WebServiceUrl;
private HttpClient httpClient;
public ApiService(string path = null)
{
_webServiceUrl = $"{_webServiceUrl}{path}/";
httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(_webServiceUrl);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Settings.Token);
}
private void HandleException(Exception ex, string url = "")
{
Settings.TotalHttpRequests -= 1;
Crashes.TrackError(ex, new Dictionary<string, string>{ { "URL", url }, });
MessagingCenter.Send<Page, string>(new Page(), "Exception", ex.Message);
}
public async Task<T> PostFormDataAsync(string url, string filePath, T t)
{
using (var form = new MultipartFormDataContent())
{
using (var fs = File.OpenRead(filePath))
{
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
fs.Close();
var json = JsonConvert.SerializeObject(t);
var data = new StringContent(json);
form.Add(new ByteArrayContent(bytes, 0, bytes.Length), "file", fs.Name);
form.Add(data, "data");
Settings.TotalHttpRequests += 1;
var result = await httpClient.PostAsync(url, form);
Settings.TotalHttpRequests -= 1;
if (result.IsSuccessStatusCode)
{
var content = await result.Content.ReadAsStringAsync();
var item = JsonConvert.DeserializeObject<T>(content);
return item;
}
else
{
await RaiseErrorAsync(result);
return default(T);
}
}
}
}
private async Task RaiseErrorAsync(HttpResponseMessage result)
{
var message = await result.Content.ReadAsStringAsync();
MessagingCenter.Send<Page, string>(new Page(), "Error", message);
}
}
I have included some code for the benefit of other Xamarin Developers.
My API endpoint is as follows:
[DisableRequestSizeLimit]
[Consumes("multipart/form-data")]
[HttpPost]
public async Task<ActionResult> Post()
{
try
{
var data = (Request.Form["data"]).ToString();
var myObject = JsonConvert.DeserializeObject<MyClass>(data);
var file = Request.Form.Files[0];
myObject = await _service.AddAsync(myObject, file);
var result = _mapper.Map<MyClassDto>(myObject);
return Ok(result);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
From this, I get my file as an IFormFile instance. I am also able to deserialize the object I sent as t of type T.
The ApiService can be modified to implement IApiService so that you can benefit from Dependency Service (in Xamarin).
On the Angular side, this is what I have on the component:
onSubmit() {
this.submitted = true;
if (this.form.invalid) {return;}
if (this.fileToUpload == null) {
Swal.fire('File', 'Please attach the file', 'error');
return;
}
const formData = new FormData();
formData.append('file', this.fileToUpload, this.fileToUpload.name);
formData.append('data', JSON.stringify(this.form.value));
this.service.postEndpoint('', formData).subscribe((data) => {
//Do something here
});
}
For the service:
import { ApiService } from '../api.service';
#Injectable({
providedIn: 'root'
})
export class MyService extends ApiService<MyClass>{
constructor(protected httpClient: HttpClient) {
super(httpClient, 'MyApiController');
}
}
The ApiService:
const httpOptions = {
headers : new HttpHeaders({
Authorization: 'Bearer ' + localStorage.getItem('token')
})
};
export abstract class ApiService<T> {
basePath = environment.apiPath;
apiURL = `${this.basePath}api/`;
constructor(protected httpClient: HttpClient, protected actionUrl: string) { }
public postEndpoint(endPoint: string, model: any): Observable<any> {
return this.httpClient.post(this.apiURL + `${this.actionUrl}/${endPoint}`, model, httpOptions);
}
}
I hope this saves someone some time! Happy coding!
It work for window phone 8.1. You can try this.
Dictionary<string, object> _headerContents = new Dictionary<string, object>();
const String _lineEnd = "\r\n";
const String _twoHyphens = "--";
const String _boundary = "*****";
private async void UploadFile_OnTap(object sender, System.Windows.Input.GestureEventArgs e)
{
Uri serverUri = new Uri("http:www.myserver.com/Mp4UploadHandler", UriKind.Absolute);
string fileContentType = "multipart/form-data";
byte[] _boundarybytes = Encoding.UTF8.GetBytes(_twoHyphens + _boundary + _lineEnd);
byte[] _trailerbytes = Encoding.UTF8.GetBytes(_twoHyphens + _boundary + _twoHyphens + _lineEnd);
Dictionary<string, object> _headerContents = new Dictionary<string, object>();
SetEndHeaders(); // to add some extra parameter if you need
httpWebRequest = (HttpWebRequest)WebRequest.Create(serverUri);
httpWebRequest.ContentType = fileContentType + "; boundary=" + _boundary;
httpWebRequest.Method = "POST";
httpWebRequest.AllowWriteStreamBuffering = false; // get response after upload header part
var fileName = Path.GetFileName(MediaStorageFile.Path);
Stream fStream = (await MediaStorageFile.OpenAsync(Windows.Storage.FileAccessMode.Read)).AsStream(); //MediaStorageFile is a storage file from where you want to upload the file of your device
string fileheaderTemplate = "Content-Disposition: form-data; name=\"{0}\"" + _lineEnd + _lineEnd + "{1}" + _lineEnd;
long httpLength = 0;
foreach (var headerContent in _headerContents) // get the length of upload strem
httpLength += _boundarybytes.Length + Encoding.UTF8.GetBytes(string.Format(fileheaderTemplate, headerContent.Key, headerContent.Value)).Length;
httpLength += _boundarybytes.Length + Encoding.UTF8.GetBytes("Content-Disposition: form-data; name=\"uploadedFile\";filename=\"" + fileName + "\"" + _lineEnd).Length
+ Encoding.UTF8.GetBytes(_lineEnd).Length * 2 + _trailerbytes.Length;
httpWebRequest.ContentLength = httpLength + fStream.Length; // wait until you upload your total stream
httpWebRequest.BeginGetRequestStream((result) =>
{
try
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
using (Stream stream = request.EndGetRequestStream(result))
{
foreach (var headerContent in _headerContents)
{
WriteToStream(stream, _boundarybytes);
WriteToStream(stream, string.Format(fileheaderTemplate, headerContent.Key, headerContent.Value));
}
WriteToStream(stream, _boundarybytes);
WriteToStream(stream, "Content-Disposition: form-data; name=\"uploadedFile\";filename=\"" + fileName + "\"" + _lineEnd);
WriteToStream(stream, _lineEnd);
int bytesRead = 0;
byte[] buffer = new byte[2048]; //upload 2K each time
while ((bytesRead = fStream.Read(buffer, 0, buffer.Length)) != 0)
{
stream.Write(buffer, 0, bytesRead);
Array.Clear(buffer, 0, 2048); // Clear the array.
}
WriteToStream(stream, _lineEnd);
WriteToStream(stream, _trailerbytes);
fStream.Close();
}
request.BeginGetResponse(a =>
{ //get response here
try
{
var response = request.EndGetResponse(a);
using (Stream streamResponse = response.GetResponseStream())
using (var memoryStream = new MemoryStream())
{
streamResponse.CopyTo(memoryStream);
responseBytes = memoryStream.ToArray(); // here I get byte response from server. you can change depends on server response
}
if (responseBytes.Length > 0 && responseBytes[0] == 1)
MessageBox.Show("Uploading Completed");
else
MessageBox.Show("Uploading failed, please try again.");
}
catch (Exception ex)
{}
}, null);
}
catch (Exception ex)
{
fStream.Close();
}
}, httpWebRequest);
}
private static void WriteToStream(Stream s, string txt)
{
byte[] bytes = Encoding.UTF8.GetBytes(txt);
s.Write(bytes, 0, bytes.Length);
}
private static void WriteToStream(Stream s, byte[] bytes)
{
s.Write(bytes, 0, bytes.Length);
}
private void SetEndHeaders()
{
_headerContents.Add("sId", LocalData.currentUser.SessionId);
_headerContents.Add("uId", LocalData.currentUser.UserIdentity);
_headerContents.Add("authServer", LocalData.currentUser.AuthServerIP);
_headerContents.Add("comPort", LocalData.currentUser.ComPort);
}
Top to #loop answer.
We got below error for Asp.Net MVC,
Unable to connect to the remote server
Fix:
After adding the below code in Web.Confing issue has been resolved for us
<system.net>
<defaultProxy useDefaultCredentials="true" >
</defaultProxy>
</system.net>
Base on #Wolf5 's answer This works for me
var client = new WebClient();
client.Encoding = Encoding.UTF8;
var boundary = $"--------------------------{DateTime.Now.Ticks:x}";
client.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
client.Headers.Add("Cookie", cookie);
var start = $"--{boundary}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{Path.GetFileName(fileName)}\"\r\nContent-Type: image/jpeg\r\n\r\n";
var end = $"\r\n--{boundary}--\r\n";
var lst = new List<byte>();
lst.AddRange(client.Encoding.GetBytes(start));
lst.AddRange(File.ReadAllBytes(fileName));
lst.AddRange(client.Encoding.GetBytes(end));
var resp = client.UploadData($"{ApiUrl}/api/upload/image", "POST", lst.ToArray());

How to upload video on Dailymotion with c# ?? Is somebody has a complete code?

I wish upload a video on dailymotion with c# code , but dailymotion doesn't provide c# code to upload video with c#.
I search on dailymotion documentation api and i found this not explicit curl code :
curl -F 'access_token=...' \
-F 'url=http://upload-02.dailymotion.com/files/5ccb48b8e8aef3fcb8959739f993e1b9.3gp' \
https://api.dailymotion.com/me/videos
and i tryed to transpose but it's not working:
string contentFile = "c:\name_of_my_video_file.flv";
byte[] byteArray = Encoding.ASCII.GetBytes(contentFile);
MemoryStream fs = new MemoryStream(byteArray);
// Provide the WebPermission Credintials
// Create a request using a URL that can receive a post.
string uri = "https://api.dailymotion.com/me/videos";
WebRequest request = WebRequest.Create(uri);
// Set the Method property of the request to POST.
request.Method = "POST";
request.Credentials = new NetworkCredential("logindailymotion","passworddailymotion");
// Create POST data and convert it to a byte array.
string postData = "access_token=my_api_key&url=http://upload-02.dailymotion.com/files/name_of_my_video_file.flv";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
// Notify the server about the size of the uploaded file
request.ContentLength = fs.Length;
// The buffer size is set to 2kb
int buffLength = 2048;
byte[] buff = new byte[buffLength];
int contentLen;
// Opens a file stream (System.IO.FileStream) to read the file to be uploaded
//FileStream fs = fileInf.OpenRead();
try
{
// Stream to which the file to be upload is written
Stream strm = request.GetRequestStream();
// Read from the file stream 2kb at a time
contentLen = fs.Read(buff, 0, buffLength);
// Till Stream content ends
while (contentLen != 0)
{
// Write Content from the file stream to the FTP Upload Stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// Close the file stream and the Request Stream
strm.Close();
fs.Close();
}
catch (Exception ex)
{
throw ex;
}
}
Is there a better documentation for c# code ?
Is somebody has the correct code ?
I created a complete example to answer your question and upload a video. It is available on GitHub now.
Edit: I used API information available explaining how to do their OAuth Authentication and Video Publishing.
Here is all the code except for the objects that are deserialized from JSON:
Code
static void Main(string[] args)
{
var accessToken = GetAccessToken();
Authorize(accessToken);
Console.WriteLine("Access token is " + accessToken);
var fileToUpload = #"C:\Program Files\Common Files\Microsoft Shared\ink\en-US\join.avi";
Console.WriteLine("File to upload is " + fileToUpload);
var uploadUrl = GetFileUploadUrl(accessToken);
Console.WriteLine("Posting to " + uploadUrl);
var response = GetFileUploadResponse(fileToUpload, accessToken, uploadUrl);
Console.WriteLine("Response:\n");
Console.WriteLine(response + "\n");
Console.WriteLine("Publishing video.\n");
var uploadedResponse = PublishVideo(response, accessToken);
Console.WriteLine(uploadedResponse);
Console.WriteLine("Done. Press enter to exit.");
Console.ReadLine();
}
private static UploadResponse GetFileUploadResponse(string fileToUpload, string accessToken, string uploadUrl)
{
var client = new WebClient();
client.Headers.Add("Authorization", "OAuth " + accessToken);
var responseBytes = client.UploadFile(uploadUrl, fileToUpload);
var responseString = Encoding.UTF8.GetString(responseBytes);
var response = JsonConvert.DeserializeObject<UploadResponse>(responseString);
return response;
}
private static UploadedResponse PublishVideo(UploadResponse uploadResponse, string accessToken)
{
var request = WebRequest.Create("https://api.dailymotion.com/me/videos?url=" + HttpUtility.UrlEncode(uploadResponse.url));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("Authorization", "OAuth " + accessToken);
var requestString = String.Format("title={0}&tags={1}&channel={2}&published={3}",
HttpUtility.UrlEncode("some title"),
HttpUtility.UrlEncode("tag1"),
HttpUtility.UrlEncode("news"),
HttpUtility.UrlEncode("true"));
var requestBytes = Encoding.UTF8.GetBytes(requestString);
var requestStream = request.GetRequestStream();
requestStream.Write(requestBytes, 0, requestBytes.Length);
var response = request.GetResponse();
var responseStream = response.GetResponseStream();
string responseString;
using (var reader = new StreamReader(responseStream))
{
responseString = reader.ReadToEnd();
}
var uploadedResponse = JsonConvert.DeserializeObject<UploadedResponse>(responseString);
return uploadedResponse;
}
private static string GetAccessToken()
{
var request = WebRequest.Create("https://api.dailymotion.com/oauth/token");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var requestString = String.Format("grant_type=password&client_id={0}&client_secret={1}&username={2}&password={3}",
HttpUtility.UrlEncode(SettingsProvider.Key),
HttpUtility.UrlEncode(SettingsProvider.Secret),
HttpUtility.UrlEncode(SettingsProvider.Username),
HttpUtility.UrlEncode(SettingsProvider.Password));
var requestBytes = Encoding.UTF8.GetBytes(requestString);
var requestStream = request.GetRequestStream();
requestStream.Write(requestBytes, 0, requestBytes.Length);
var response = request.GetResponse();
var responseStream = response.GetResponseStream();
string responseString;
using (var reader = new StreamReader(responseStream))
{
responseString = reader.ReadToEnd();
}
var oauthResponse = JsonConvert.DeserializeObject<OAuthResponse>(responseString);
return oauthResponse.access_token;
}
private static void Authorize(string accessToken)
{
var authorizeUrl = String.Format("https://api.dailymotion.com/oauth/authorize?response_type=code&client_id={0}&scope=read+write+manage_videos+delete&redirect_uri={1}",
HttpUtility.UrlEncode(SettingsProvider.Key),
HttpUtility.UrlEncode(SettingsProvider.CallbackUrl));
Console.WriteLine("We need permissions to upload. Press enter to open web browser.");
Console.ReadLine();
Process.Start(authorizeUrl);
var client = new WebClient();
client.Headers.Add("Authorization", "OAuth " + accessToken);
Console.WriteLine("Press enter once you have authenticated and been redirected to your callback URL");
Console.ReadLine();
}
private static string GetFileUploadUrl(string accessToken)
{
var client = new WebClient();
client.Headers.Add("Authorization", "OAuth " + accessToken);
var urlResponse = client.DownloadString("https://api.dailymotion.com/file/upload");
var response = JsonConvert.DeserializeObject<UploadRequestResponse>(urlResponse).upload_url;
return response;
}
Again, I put it on GitHub.

Categories

Resources