Streaming large file across multiple layers - c#

Large zip file (in gigabytes) is stored in API layer. When a user clicks download button in the browser the request goes through WEB tier to the API tier and in return we need to stream the large file from API tier to WEB tier back to the client browser.
Please advice how can I stream large file from API application to WEB application to client without writing the file in web application?
The Web application request API applications using rest sharp library, it would be great if you can advice a solution using rest sharp (alternatively native code). Both the projects are in .NET core 2.2

Are you looking for DownloadData?
https://github.com/restsharp/RestSharp/blob/master/src/RestSharp/RestClient.Sync.cs#L23
The following is directly from the example in the docs:
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);

Found the solution by using HttpClient instead of RestSharp library for downloading the content directly to browser
The code snippet is as below
HttpClient client = new HttpClient();
var fileName = Path.GetFileName(filePath);
var fileDowloadURL = $"API URL";
var stream = await client.GetStreamAsync(fileDowloadURL).ConfigureAwait(false);
// note that at this point stream only contains the header the body content is not read
return new FileStreamResult(stream, "application/octet-stream")
{
FileDownloadName = fileName
};

Related

How to read the content of a BIM 360 file as a filestream and writes it to another stream

I was looking into this document
AutoDesk
I am able to get Files/Folders structure and content from BIM 360 but is there a way I can read the content of a file as file stream to write it in different file(I don't want to download the file locally) in .Net core without using rest end point.
The getObject method (from the official Forge SDK) that is typically used to access OSS data (which BIM 360 Docs uses under the hood as well) does return System.IO.Stream already. So you should be able to stream the incoming data anywhere you need. For example, you can redirect the stream to another POST request as explained in this tutorial:
var request = new HttpRequestMessage(HttpMethod.Post, "/some/endpoint");
using (var requestContent = new StreamContent(stream))
{
request.Content = requestContent;
using (var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStreamAsync();
}
}

WebAPI - File download checksum?

I'm currently downloading a file from my Web API using a C# RestClient.
This is my current code for returning a file from the Web API part:
[HttpGet]
public HttpResponseMessage Generate()
{
var stream = new MemoryStream();
// processing the stream.
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(stream.GetBuffer())
};
result.Content.Headers.ContentDisposition =
new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = "CertificationCard.pdf"
};
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
Taken from this: How to return a file (FileContentResult) in ASP.NET WebAPI
My question is then, how can i validate that the file is downloaded correctly - can i somehow provide an MD5 checksum on the ByteArray and check this in the RestClient, or is this complete unnecessary?
You would generate a hash of the file, add it as a response header and verify when the download completes within the client.
This would only make sense if you think there is a chance of corruption of the data within your stream or network issues outside the ability of TCP error correction to handle.
How necessary this is is a judgement call, see Why is it good practice to compare checksums when downloading a file? for a discussion. (Considering the hash & data originate from the same place in the same response, the security considerations don't really apply)

How to read data from WebClient.UploadData

First time posting! I've been breaking my head on this particular case. I've got a Web application that needs to upload a file towards a web-api and receive an SVG file (in a string) back.
The web-app uploads the file as follows:
using (var client = new WebClient())
{
var response = client.UploadFile(apiUrl, FileIGotEarlierInMyCode);
ViewBag.MessageTest = response.ToString();
}
Above works, but then we get to the API Part:
How do I access the uploaded file? Pseudocode:
public string Post([FromBody]File f)
{
File uploadedFile = f;
String svgString = ConvertDataToSVG(uploadedFile);
return s;
}
In other words: How do I upload/send an XML-file to my Web-api, use/manipulate it there and send other data back?
Thanks in advance!
Nick
PS: I tried this answer:
Accessing the exact data sent using WebClient.UploadData on the server
But my code did not compile on Request.InputStream.
The reason Request.InputStream didn't work for you is that the Request property can refer to different types of Request objects, depending on what kind of ASP.NET solution you are developing. There is:
HttpRequest, as available in Web Forms,
HttpRequestBase, as available in MVC Controllers
HttpRequestMessage, as available in Web API Controllers.
You are using Web API, so HttpRequestMessage it is. Here is how you read the raw request bytes using this class:
var data = Request.Content.ReadAsByteArrayAsync().Result;

How to stream data from another resource in c# WebApi

I'm working on an MVC webapplication that streams data from many resources.
My problem is when want to get data (music file) from a stream resource and then stream it to my web page, I don't know how not to download completely and then stream it to my web page.
Here is my webapi code:
[HttpGet]
public HttpResponseMessage Downlaod(int Data)
{
WebClient myWebClient = new WebClient();
Uri u =new Uri("https://api.soundcloud.com/tracks/" + Data + "/stream?client_id=*******************");
byte[] myDataBuffer = myWebClient.DownloadData(u);
MemoryStream st = new MemoryStream(myDataBuffer);
/*heres when i download data and convert it to memory stream*/
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Headers.AcceptRanges.Add("bytes");
result.StatusCode = HttpStatusCode.OK;
result.Content = new StreamContent(st);
result.Content.Headers.ContentLength = st.Length;
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
I want to stream immediately when I receive bytes from my resource.
note: I'm not asking about how to stream data to the client it's about streaming from server to server.
I want to get file from another server and stream it to my clients without downloading the full content before start streaming.
note2: I also don't want to download the full content in once because the full content is very big, I want to get a byte from my content and then send that byte to the client not downloading the full content.
I think I'm doing it in wrong way and it is not possible with an MVC application if anyone can introduce an application that can proxy bytes from destination to client it would be the answer. the main reason that I want this,is to proxy a music file from my content server to a javascript music player and not to expose the main file.

calling a Asp.net web API from c# with multiple of parameters

I have a web api that has parameters. I am trying to call the api from another application. This is not a problem on the client side using, but i cannot find a way to do it on the server side in c#. Thanks for any advice.
You can call Web API from any desktop or server side application using WebClient.
var webClient = new WebClient();
webClient.Headers["Content-Type"] = "application/json";
webClient.Headers["X-JavaScript-User-Agent"] = "Google APIs Explorer";
var json = Newtonsoft.Json.JsonConvert.SerializeObject(new { longUrl = url });
var data = webClient.UploadString("https://www.googleapis.com/urlshortener/v1/url?pp=1", json);
http://weblogs.asp.net/pglavich/archive/2012/02/18/mvc4-and-web-api-make-an-api-the-way-you-always-wanted-part-1.aspx
The link above worked perfectly for me.

Categories

Resources