How to stream data from another resource in c# WebApi - c#

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.

Related

Streaming large file across multiple layers

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

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 get files from different folders compress them and return them to mobile client from asp.net web api service

Actually I'm trying to return multiple files(within same response as result to jQuery mobile client request) which include(html, .js, .css, .png images files) altogether at one time so that mobile client can download them as new updates. And I have been asked to make it a POST request rather than a GET request anyway.
Here is my Web API code
[Route("availableupdates")]
[HttpPost]
public HttpResponseMessage FilePackage()
{
HttpResponseMessage response = null;
var localFilePath = Directory.GetFiles(#"C:\Temp\Flower_Shop\Flower_Shop\images\i.png");
if (!File.Exists(localFilePath[0]))
{
response = Request.CreateResponse(HttpStatusCode.Gone);
}
else
{
response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StreamContent(new FileStream(localFilePath[0], FileMode.Open, FileAccess.Read));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "i";
}
return response;
}
Now the thing is that all those (html, .js, .css, .png) files are part of another little mobile app (and apparently lying in different folders within same application) which is sitting on the same server as the Web API RESTFUL service itself and in the code above I just hardcoded physical path of one of the image files. I don't know how to get all the files from different folders and sub-folders and compress them together and send them to the client.
Another big thing that I will really appreciate if someone explains me what MIMETYPE will work for the compressed files and do I need to send the compressed files as JSON response as I don't really know that It would be a good idea to send back a JSON response. What will happen to the contents of the files? Will the contents be converted into JSON as well?

Return a Stream and write it to disk?

I have an ASP.Net Web API project that is returning a response HttpResponseMessage, I'm setting the content of that message to a StreamContent that has been initialized with a Stream
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, channelId);
response.Content = new StreamContent(myStream);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
return response;
I'm trying to some rudimentary local caching of the file represented by the stream, can I both return the stream and write it to disk without having to wait for it to finish writing it to disk before returning it to the requester?
Alternate method I'm considering would be to have a queue of files to load into my local cache and add the id of the requested file to the queue then send the stream back as a response. Then have a separate worker process the queue so that file can be retrieved from my local cache next time.

Storing an image from a webservice

I am accessing an API that returns a favicon for a specified domain (http://getfavicon.appspot.com/). I have a long list of domains that I want to get Icons for and don't want to make the call to the web service every time, so I figured I would get the response and store the image either on the file system or in a DB Blob.
However. I don't know how to get something meaningful from the response stream that comes back from the service.
byte[] buf = new byte[8192];
var request = (HttpWebRequest)WebRequest.Create("http://getfavicon.appspot.com/http://stackoverflow.com");
var response = (HttpWebResponse)request.GetResponse();
var resStream = response.GetResponseStream();
I've got as far as here to get a response back, but how would I can I treat this as something I can save to a SQL DB or out to the filesystem?
Am I missing something simple?
Thanks
If you use the System.Net.WebClient class, you can do this a little easier.
This will download the URL and save it to a local file:
var client = new System.Net.WebClient();
client.DownloadFile(
// Url to download
#"http://getfavicon.appspot.com/http://stackoverflow.com",
// Filename of where to save the downloaded content
"stackoverflow.com.ico");
If you want a byte[] instead, use the DownloadData method.

Categories

Resources