Null response when using RestSharp to download a file - c#

I am attempting to update the RestSharp file download portion code in one of my applications. Apparently the .SaveAs() is being depricated, so I'm trying to follow their updated example for working with files. However, my response is always null, and the temp file that is created doesn't seem to be filled with the data I'm attempting to save.
Here's what I have so far:
var tempFile = Path.GetTempFileName();
using var writer = File.OpenWrite(tempFile);
var client = new RestClient("https://provider-api.spotify.com/v1/analytics");
var request = new RestRequest("{licensor}/enhanced/tracks/{year}/{month}/{day}", Method.GET);
request.AddHeader("Authorization", $#"Bearer {token}");
request.AddUrlSegment("licensor", "licensor_name");
request.AddUrlSegment("year", 2021);
request.AddUrlSegment("month", 1);
request.AddUrlSegment("day", 10);
var checkResponse = client.Execute<SpotifyTracksResourceModel>(request);
if (checkResponse.Content == "")
{
Console.WriteLine("No data");
}
request.ResponseWriter = responseStream =>
{
using (responseStream)
{
responseStream.CopyTo(writer);
}
};
var response = client.DownloadData(request);
I threw in the checkResponse code to ensure that I am actually getting data back, and I am in fact getting data. But as I said, once it gets to the var response = ... line, it comes back NULL, and nothing has been written to that temp file.
Thank you in advance for any help with this!

So it ended up being a combination of a few little things I needed to tweak. But the biggest things were updating the RestSharp NuGet package, and closing off the writer FileStream.
var tempFile = Path.GetTempFileName();
using var writer = File.OpenWrite(tempFile);
var client = new RestClient("https://provider-api.spotify.com/v1/analytics");
var request = new RestRequest("{licensor}/enhanced/tracks/{year}/{month}/{day}", DataFormat.Json)
.AddUrlSegment("licensor", "licensor_name")
.AddUrlSegment("year", "2021")
.AddUrlSegment("month", "1")
.AddUrlSegment("day", "10");
spotifyRequest.AddHeader("Authorization", $#"Bearer {token}");
var checkResponse = spotifyClient.Get<SpotifyTracksResourceModel>(spotifyRequest);
request.ResponseWriter = responseStream =>
{
using (responseStream)
{
responseStream.CopyTo(writer);
}
};
var response = client.DownloadData(request);
writer.Close();

Related

Getting Some Randam ID when Sending a file using MultipartContent() and HttpClient

I am trying to send a file via an API. I was able to receive the file in my API, but for some reason I am seeing random ID(could be content id) when I read the content in my API.
Previously I was using seeing info about content type and file info as well. I was using MultipartFormDataContent() at that time, then I switched to MultipartContent(). Now the content type and file info is gone, but I still see the id at the start and end of the content.
Code that I am using to send file
using (var formContent = new MultipartContent())
{
byte[] fileByteArray;
using (var binaryReader = new BinaryReader(file.OpenReadStream()))
{
fileByteArray = binaryReader.ReadBytes((int)file.Length);
}
var content = new ByteArrayContent(fileByteArray, 0, fileByteArray.Length);
formContent.Add(content);
// Add the file and it's content
formContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(file.ContentType);
formContent.Headers.ContentType.CharSet = string.Empty;
formContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data");
HttpClient httpClient = new HttpClient();
var task = Task.Run(() => httpClient.PostAsync("MY_END_POINT", formContent));
task.Wait();
HttpResponseMessage response = task.Result;
response.EnsureSuccessStatusCode();
}
Code to read file
using (StreamReader reader = new StreamReader(fileUpload.FileContent))
{
string content = reader.ReadToEnd();
}
Any idea on how the id can be removed?

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

Document uploaded to MS Teams using graph API gets corrupted

I am trying to upload a document to Microsoft Teams using Microsoft Graph (beta version), but the document gets corrupted after a successful upload.
Using Graph, I'm first creating an Group, creating a Team based on the Group, adding some Team Members and finally uploading a document to the default channel.
All works fine except the uploaded document gets corrupted and the Office Online editor is not able to open it. We can however download the file and open in Microsoft Word after correcting the file.
Below is the code that I'm using for document upload->
FileInfo fileInfo =
new FileInfo(#"F:\Projects\TestProjects\MSTeamsSample\MSTeamsSample\Files\Test File.docx");
var bytes = System.IO.File.ReadAllBytes(fileInfo.FullName);
var endpoint = $"https://graph.microsoft.com/beta/groups/{groupId}/drive/items/root:/General/{fileInfo.Name}:/content";
var fileContent = new ByteArrayContent(bytes);
fileContent.Headers.ContentType =
MediaTypeHeaderValue.Parse("application/octet-stream");
var requestContent = new MultipartFormDataContent();
requestContent.Add(fileContent, "File", fileInfo.Name);
var request = new HttpRequestMessage(HttpMethod.Put, endpoint);
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", "<Access Token>");
request.Content = requestContent;
var client = new HttpClient();
var response = client.SendAsync(request).Result;
I tried changing content type to application/vnd.openxmlformats-officedocument.wordprocessingml.document but no luck. I don't understand what could be wrong here. The code is pretty straight forward, based on the this documentation. Any help will be highly appreciated.
Please try this:
var filePath = #"F:\Projects\TestProjects\MSTeamsSample\MSTeamsSample\Files\Test File.docx";
var fileName = Path.GetFileName(filePath);
var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var endpoint = $"https://graph.microsoft.com/beta/groups/{groupId}/drive/items/root:/General/{fileName}:/content";
using (var client = new HttpClient())
{
using (var content = new StreamContent(fileStream))
{
content.Headers.Add("Content-Type", MimeMapping.GetMimeMapping(fileName));
// Construct the PUT message towards the webservice
using (var request = new HttpRequestMessage(HttpMethod.Put, endpoint))
{
request.Content = content;
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse.Token);
// Request the response from the webservice
using (var response = await client.SendAsync(request))
{
// Check the response.
}
}
}
}
I am able to see Word document in Microsoft Teams editor.

Not receiving JSON data from Microsoft FaceAPI

I am trying to get JSON data from a picture using Microsoft's FaceAPI. I am receiving a StatusCode OK, but am not getting anything significant back. I have verified that the MemoryStream has the right data (which I am getting from an Image control) by saving it to a file.
private async Task<string> GetJSON()
{
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "mykey");
// Request parameters
queryString["returnFaceId"] = "true";
queryString["returnFaceLandmarks"] = "false";
var uri = "https://api.projectoxford.ai/face/v1.0/detect?" + queryString;
HttpResponseMessage response;
// Request body
byte[] byteData = ImageToByte();
using (var content = new ByteArrayContent(byteData))
{
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response = await client.PostAsync(uri, content);
}
return "";
}
private byte[] ImageToByte()
{
using (MemoryStream stream = new MemoryStream())
{
videoBox.Dispatcher.Invoke(delegate
{
var encoder = new PngBitmapEncoder();
var flippedBitmap = new TransformedBitmap();
flippedBitmap.BeginInit();
flippedBitmap.Source = (BitmapSource)videoBox.Source;
var transform = new ScaleTransform(-1, 1);
flippedBitmap.Transform = transform;
flippedBitmap.EndInit();
encoder.Frames.Add(BitmapFrame.Create(flippedBitmap));
encoder.Save(stream);
});
using (FileStream test = new FileStream("snapshot.bmp", FileMode.Create))
{
stream.Position = 0;
stream.CopyTo(test);
}
return stream.ToArray();
}
}
You'll want to call await response.Content.ReadAsStringAsync() to get the JSON.
Alternatively, you can use the Microsoft.ProjectOxford.Face NuGet package which does the plumbing for you, plus provide C# types thereby relieving you the tedium of parsing the JSON.
I am not a c# programmer but after looking at your code, method GetJSON is returning hard coded empty string that might be the cause you are not getting anything back from the server after invoking this method or second reason could be your asynchronous server configuration is not working properly thus its returning blank first and doing actual operation later.

How to process multipart/mixed in C#

Fiddler shows that server processed my request successfully. I get back a boundary-separated list of HTTP responses. But processing multipart/mixed response is new to me.
Based upon research, I tried the following:
httpResp = (HttpWebResponse)httpRequest.GetResponse() as HttpWebResponse;
var content = new StreamContent(httpResp.GetResponseStream());
var streamProvider = new MultipartMemoryStreamProvider();
var task = content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
{
foreach (HttpContent item in streamProvider.Contents) {
log.Debug("in foreach");
partResStr = item.ReadAsStringAsync().Result;
log.DebugFormat("partResStr = {0}", partResStr);
}
});
But the logging on the foreach doesn't occur.
When I did this, I had to set the ContentType of the StreamContent:
var streamContent = new StreamContent(stream);
streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(HttpContext.Current.Request.ContentType);
var provider = streamContent.ReadAsMultipartAsync().Result;

Categories