I am trying to upload a file to Onedrive using RestSharp and Graph API. Basically I want to upload an Excel file. However, even the file saves, there is problem with the content. I am using:
https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/item_uploadcontent
using the code:
string newToken = "bearer ourtoken";
var client = new RestClient("https://xxx-my.sharepoint.com/_api/v2.0/"+ oneDrivePath + Path.GetFileName(filePathWithName) + ":/content");
var request = new RestRequest(Method.PUT);
request.RequestFormat = DataFormat.Json;
request.AddHeader("Authorization", newToken);
request.AddHeader("Content-Type", "text/plain");
byte[] sContents;
FileInfo fi = new FileInfo(filePathWithName);
// Disk
FileStream fs = new FileStream(filePathWithName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
sContents = br.ReadBytes((int)fi.Length);
br.Close();
fs.Close();
request.AddBody(Convert.ToBase64String(sContents));
var response = client.Execute(request);
This uploads the file however the XLSX file becomes corrupted.
Basically I need to figure out how to pass the stream to the RestSharp request.
Solved it by changing RestClient to HttpClient.
string newToken = "bearer mytoken"
using (var client = new HttpClient())
{
var url = "https://xxx-my.sharepoint.com/_api/v2.0/" + oneDrivePath + Path.GetFileName(filePathWithName) + ":/content";
client.DefaultRequestHeaders.Add("Authorization", newToken);
byte[] sContents = File.ReadAllBytes(filePathWithName);
var content = new ByteArrayContent(sContents);
var response = client.PutAsync(url, content).Result;
return response;
}
Related
I have an API which is returning HTTPResponse with Content of type "Stream Content". Now i want to consume this API in another application and download the zip file sent as stream content. Can someone please suggest how can I achieve this in C#?
private HttpResponseMessage GetHttpResponseMessageForConfigFile(Component component)
{
var result = Request.CreateResponse(HttpStatusCode.OK);
component.ConfigData = _configDataService.GetConfigDetail(component.Id).Data;
var mermoryStream = new MemoryStream(component.ConfigData);
result.Content = new StreamContent(mermoryStream);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = string.Format("{0}.zip", component.Code)
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return result;
}
In the above, component.ConfigData contains a byte array of zip file.
You download a ZIP file like any other binary file as well:
using (WebClient client = new WebClient())
{
client.DownloadFile(new Uri(url), #"c:\path\to\file.zip");
}
I have been struggling to download a simple pdf hosted online using restsharp. I have been playing around with the code for over an hour and all I get are null object results.
The file downloads easily in POSTMAN using a GET and no content header set but still what gives?
Below is the noddy sandbox test I have been experimenting around with:
[TestFixture]
public class Sandbox
{
[Test]
public void Test()
{
var uri = "https://www.nlm.nih.gov/mesh/2018/download/2018NewMeShHeadings.pdf";
var client = new RestClient();
var request = new RestRequest(uri, Method.GET);
//request.AddHeader("Content-Type", "application/octet-stream");
byte[] response = client.DownloadData(request);
File.WriteAllBytes(#"C:\temp\1.pdf", response);
}
}
Update: Return a Stream
var baseUri = "https://www.nlm.nih.gov/mesh/2018/download/";
var client = new RestClient(baseUri);
var request = new RestRequest("2018NewMeShHeadings.pdf", Method.GET);
request.AddHeader("Content-Type", "application/octet-stream");
var tempFile = Path.GetTempFileName();
var stream = File.Create(tempFile, 1024, FileOptions.DeleteOnClose);
request.ResponseWriter = responseStream => responseStream.CopyTo(stream);
var response = client.DownloadData(request);
The stream is now populated with the downloaded data.
Try this:
var uri = "https://www.nlm.nih.gov/mesh/2018/download/";
var client = new RestClient(uri);
var request = new RestRequest("2018NewMeShHeadings.pdf", Method.GET);
//request.AddHeader("Content-Type", "application/octet-stream");
byte[] response = client.DownloadData(request);
I am putting together a test application using WebApi2 and HttpClient in a win forms app.
I have come accross an issue where my HttpClient request to a WebApi2 controller which returns an HttpResponseMessage doesnt return the ByteArrayContent.
WebApiController Code
[HttpGet]
public HttpResponseMessage DownloadFilePart(string fileName)
{
var path = Server.MapPath("~/App_Data/uploads/" + fileName);
var fileArray = System.IO.File.ReadAllBytes(path);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(fileArray)
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue(System.Web.MimeMapping.GetMimeMapping(fileName));
response.Content.Headers.ContentLength = fileArray.Length;
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
return response;
}
WinForms Code using HttpClient
static async void GetFilePart(string hostrUri)
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(hostrUri)
};
var request = new HttpRequestMessage(HttpMethod.Get, "/Home/DownloadFilePart/?fileName=Test.txt");
var responseMessage = httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var memoryStream = new MemoryStream();
var stream = await responseMessage.Result.Content.ReadAsByteArrayAsync();
var fileToWriteTo = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\Temp\\Test.txt";
using (var fileStream = new FileStream(fileToWriteTo, FileMode.Create, FileAccess.Write, FileShare.None))
{
//copy the content from response to filestream
fileStream.Write(stream, 0, stream.Length);
}
}
When the request return from the WebApi and I write the bytes to file all that is written into the file is the actual headers from the WebApi response. Has anyone any ideas what the issue could be here?
Thanks
Your problem is here
httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
HttpCompletionOption.ResponseHeadersRead is summarized as
The operation should complete as soon as a response is available and headers are read. The content is not read yet.
This would explain why you only get the headers in your response.
Either remove it completely or change it to HttpCompletionOption.ResponseContentRead
static async void GetFilePart(string hostrUri)
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(hostrUri)
};
var request = new HttpRequestMessage(HttpMethod.Get, "/Home/DownloadFilePart/?fileName=Test.txt");
var responseMessage = await httpClient.SendAsync(request);
var byteArray = await responseMessage.Content.ReadAsByteArrayAsync();
var fileToWriteTo = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\Temp\\Test.txt";
using (var fileStream = new FileStream(fileToWriteTo, FileMode.Create, FileAccess.Write, FileShare.None))
{
//copy the content from response to filestream
fileStream.Write(byteArray, 0, byteArray.Length);
}
}
I have an 'ASP.NET' console application and I use 'RestSharp' client for Dropbox.
I use this code to download a file :
var baseUrl = "https://content.dropboxapi.com";
var client = new RestClient(baseUrl);
client.Authenticator = OAuth1Authenticator.ForRequestToken(mc_apiKey, mc_appsecret);
RestRequest request = new RestRequest(string.Format("/{0}/files/auto", mc_version), Method.GET);
client.Authenticator = OAuth1Authenticator.ForProtectedResource(mc_apiKey, mc_appsecret, accessToken.Token, accessToken.Secret);
request.AddParameter("path", path);
var responseAccount = client.Execute(request);
var fileString = responseAccount.Content;
byte[] b1 = System.Text.Encoding.UTF8.GetBytes (fileString);
When call client.Execute(request)the whole file is loaded in memory, so when I have a very largefile in Dropbox the program will crash.
I need to get the file to stream without using client.DownloadData(request).SaveAs(path) to download to local storage.
I need to be able to stream the file in chunks.
You can set the request.ResponseWriter like so :
var baseUrl = "https://content.dropboxapi.com";
var client = new RestClient(baseUrl);
client.Authenticator = OAuth1Authenticator.ForRequestToken(mc_apiKey,mc_appsecret);
RestRequest request = new RestRequest(string.Format("/{0}/files/auto", mc_version), Method.GET);
client.Authenticator = OAuth1Authenticator.ForProtectedResource(mc_apiKey, mc_appsecret, accessToken.Token, accessToken.Secret);
request.AddParameter("path", path);
string tempFile = Path.GetTempFileName();
using(var stream = File.Create(tempFile, 1024, FileOptions.DeleteOnClose ))
{
request.ResponseWriter = (responseStream) => responseStream.CopyTo(stream);
var response = client.DownloadData(request);
}
You can see the example from the docs here
I found the best answer in link:
string url = String.Format("https://content.dropboxapi.com/1/files/auto{0}?oauth_consumer_key={1}&oauth_token={2}&oauth_signature={3}%26{4}", path, app-key, access-token, app-secret, access-token-secret);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "Get";
WebResponse webResponse = null;
try
{
webResponse = webRequest.GetResponse();
return webResponse.GetResponseStream();
}
catch (Exception ex)
{
throw ex;
}
I have a app in which user can record video and an api to upload recorded video to azure.
I am using below code
HttpClientHandler handler = new HttpClientHandler();
handler.MaxRequestContentBufferSize = int.MaxValue;
using (HttpClient httpClient = new HttpClient(handler)
{
MaxResponseContentBufferSize = int.MaxValue
})
{
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(new ByteArrayContent(chunks), "file", fileName);
HttpResponseMessage response = null;
response = await httpClient.PostAsync(new Uri(url), content);
return await response.Content.ReadAsStringAsync();
}
This is working only when video is less than of 10 sec. When I tried to upload video of size around 20-30 MB than it fails.
In response I got status code 404.
I also tried another way to upload. But result was same error:
string boundary = Guid.NewGuid().ToString();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "multipart/form-data;boundary=" + boundary;
StringBuilder header = new StringBuilder();
header.Append("\r\n--");
header.Append(boundary);
header.Append("\r\n");
header.Append("Content-Disposition: file; name=\"file\"; filename=\"" + fileName + "\"\r\n");
header.Append("Content-Type: application/octet-stream\r\n\r\n");
byte[] headerbytes = Encoding.UTF8.GetBytes(header.ToString());
StringBuilder footer = new StringBuilder();
footer.Append("\r\n--");
footer.Append(boundary);
footer.Append("--\r\n");
byte[] footerbytes = Encoding.UTF8.GetBytes(footer.ToString());
using (var streamWriter = await request.GetRequestStreamAsync())
{
streamWriter.Write(headerbytes, 0, headerbytes.Length);
streamWriter.Write(footerbytes, 0, footerbytes.Length);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)await request.GetResponseAsync();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
return streamReader.ReadToEnd();
}
Check the web.config of your web.api site, in particular this section
<configuration>
<system.web>
<httpRuntime maxRequestLength="xxx" />
</system.web>
</configuration>
The xxx is in KB.