Cannot download a pdf with RestSharp? - c#

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

Related

How can i save a REST Response to a PDF file? [duplicate]

I have a URL (URL for the live feed from client) which when I hit in browser returns the xml response . I have saved this in text file it`s size is 8 MB.
now my problem is that I need to save this response in xml file on server`s drive. from there I will insert this in database. and request needs to be made using code using http-client or rest-sharp library of c# .net 4.5
I am unsure what should I do for above case. can any body suggest me something
With RestSharp, it's right there in the readme:
var client = new RestClient("http://example.com");
client.DownloadData(request).SaveAs(path);
With HttpClient, it's a bit more involved. Have a look at this blog post.
Another option is Flurl.Http (disclaimer: I'm the author). It uses HttpClient under the hood and provides a fluent interface and lots of convenient helper methods, including:
await "http://example.com".DownloadFileAsync(folderPath, "foo.xml");
Get it on NuGet.
It seems SaveAs was discontinued. You can try this
var client = new RestClient("http://example.com")
byte[] response = client.DownloadData(request);
File.WriteAllBytes(SAVE_PATH, response);
In case you want async version
var request = new RestRequest("/resource/5", Method.GET);
var client = new RestClient("http://example.com");
var response = await client.ExecuteTaskAsync(request);
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception($"Unable to download file");
response.RawBytes.SaveAs(path);
Don't keep the file in memory while reading. Write it directly to the disk.
var tempFile = Path.GetTempFileName();
using var writer = File.OpenWrite(tempFile);
var client = new RestClient(baseUrl);
var request = new RestRequest("Assets/LargeFile.7z");
request.ResponseWriter = responseStream =>
{
using (responseStream)
{
responseStream.CopyTo(writer);
}
};
var response = client.DownloadData(request);
Copied from here https://stackoverflow.com/a/59720610/179017.
Add following NuGet package into the current system
dotnet add package RestSharp
Using Bearer Authentication
// Download file from 3rd party API
[HttpGet("[action]")]
public async Task<IActionResult> Download([FromQuery] string fileUri)
{
// Using rest sharp
RestClient client = new RestClient(fileUri);
client.ClearHandlers();
client.AddHandler("*", () => { return new JsonDeserializer(); });
RestRequest request = new RestRequest(Method.GET);
request.AddParameter("Authorization", string.Format("Bearer " + accessToken),
ParameterType.HttpHeader);
IRestResponse response = await client.ExecuteTaskAsync(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
// Read bytes
byte[] fileBytes = response.RawBytes;
var headervalue = response.Headers.FirstOrDefault(x => x.Name == "Content-Disposition")?.Value;
string contentDispositionString = Convert.ToString(headervalue);
ContentDisposition contentDisposition = new ContentDisposition(contentDispositionString);
string fileName = contentDisposition.FileName;
// you can write a own logic for download file on SFTP,Local local system location
//
// If you to return file object then you can use below code
return File(fileBytes, "application/octet-stream", fileName);
}
}
Using Basic Authentication
// Download file from 3rd party API
[HttpGet("[action]")]
public async Task<IActionResult> Download([FromQuery] string fileUri)
{
RestClient client = new RestClient(fileUri)
{
Authenticator = new HttpBasicAuthenticator("your user name", "your password")
};
client.ClearHandlers();
client.AddHandler("*", () => { return new JsonDeserializer(); });
RestRequest request = new RestRequest(Method.GET);
IRestResponse response = await client.ExecuteTaskAsync(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
// Read bytes
byte[] fileBytes = response.RawBytes;
var headervalue = response.Headers.FirstOrDefault(x => x.Name == "Content-Disposition")?.Value;
string contentDispositionString = Convert.ToString(headervalue);
ContentDisposition contentDisposition = new ContentDisposition(contentDispositionString);
string fileName = contentDisposition.FileName;
// you can write a own logic for download file on SFTP,Local local system location
//
// If you to return file object then you can use below code
return File(fileBytes, "application/octet-stream", fileName);
}
}

Upload video on Twitter without 3rd library

I use Hammock in the project and I want to upload videos to Twitter. I also get the "media type unrecognized" error when I try with the following code. Where part am I doing wrong?
var restClient = new Hammock.RestClient
{
Authority = "https://upload.twitter.com",
Encoding = Encoding.UTF8,
};
var restRequest = new Hammock.RestRequest
{
Credentials = credentials,
Path = "/1.1/media/upload.json",
Method = Hammock.Web.WebMethod.Post,
Encoding = Encoding.UTF8,
};
Stream stream = new MemoryStream(images);
restRequest.AddFile("media", "test", stream);
var asyncResult = restClient.BeginRequest(restRequest);
var response = restClient.EndRequest(asyncResult);
var jsonData = JsonConvert.DeserializeObject<Image>(response.Content);

c# Dropbox RestSharp download file to stream

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

Consuming compressed JSON using HttpClient and Jil

I'm a little confused about how to properly deserialize gziped Json payload from a HttpClient instance.
So far I'm doing the following, but it seems wrong. At least too complicated. Can't I feed a stream to Jil? Can't the HttpClient unzip the stream?
var client = new HttpClient();
var userEndPoint = new Uri(baseUri, "api/login");
var request = new HttpRequestMessage();
request.RequestUri = userEndPoint;
request.Method = HttpMethod.Get;
var response = _client.SendAsync(request).Result;
var userGzipByteArray = response.Content.ReadAsByteArrayAsync().Result;
var outStream = new MemoryStream();
using (var gzStream = new GZipStream(userGzipByteArray , CompressionMode.Decompress))
{
gzStream.CopyTo(outStream);
}
var userByteArray = outStream.ToArray();
var userJson = userByteArray .ConvertToString();
var user = JSON.Deserialize<User>(userJson , Jil.Options.ISO8601PrettyPrintIncludeInherited);
You can use the AutomaticDecompression flag for this. See Does .NET's HttpWebResponse uncompress automatically GZiped and Deflated responses?

mailgun email validation response

I am a newbie to Mailgun and REST and need some help.
If I use the Mailgun provided code:
RestClient client = new RestClient();
client.BaseUrl = "https://api.mailgun.net/v2";
client.Authenticator = new HttpBasicAuthenticator("api", "xxxx");
RestRequest request = new RestRequest();
request.Resource = "/address/validate";
request.AddParameter("address", "me#mydomain.com");
return client.Execute(request);
How do I retrieve and process the response that the address is valid or not?
This code works for me. I didn't use RESTClient and wrote my own code(which works perfectly fine)
[System.Web.Services.WebMethod]
public static object GetEmailInfo(string UserName)
{
var http = (HttpWebRequest)WebRequest.Create("https://api.mailgun.net/v2/address/validate?address=" + UserName);
http.Credentials = new NetworkCredential("api","public key");
http.Timeout = 5000;
try
{
var response = http.GetResponse();
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
JSON.JsonObject js = new JSON.JsonObject(content);
return Convert.ToBoolean(js["is_valid"]);
}
catch (Exception ex)
{
}
}
First of You should never post private information such as your public key of such API
Just by using the amazing Postman Chrome app you can see the result of such request:
click here to see the image below in full resolution
and I'm sure, if you instead of return client.Execute(request); you do
var result = client.Execute(request);
return result;
and adding a breakpoint in the return you can inspect what is the object that is passed from the call... without testing, I'm sure you can convert result.Content (as it's where RestSharp appends the response content) into an object and use that object (or use the dynamic type).
now, testing your code in VS:
click here to see the image below in full resolution
you can then use the dynamic object like:
click here to see the image below in full resolution
public void GetResponse()
{
var client = new RestClient();
client.BaseUrl = "https://api.mailgun.net/v2";
client.Authenticator = new HttpBasicAuthenticator("api", "pubkey-e82c8201c292691ad889ace3434df6cb");
var request = new RestRequest();
request.Resource = "/address/validate";
request.AddParameter("address", "me#mydomain.com");
var response = client.Execute(request);
dynamic content = Json.Decode(response.Content);
bool isValid = content.is_valid;
string domain = content.parts.domain;
}
and treat the content of the response just like the json passed:
{
"address": "me#mydomain.com",
"did_you_mean": null,
"is_valid": true,
"parts": {
"display_name": null,
"domain": "mydomain.com",
"local_part": "me"
}
}

Categories