Passing a Memory Stream from one API to another API - c#

I am trying to export some data to excel and store that excel in AWS S3. Our current architecture is like,
we get data from database and manipulate it as per our needs. This is done is one API call.
We need to pass that data as stream to another API ( specifically designed to interact with AWS S3)
Store that stream as Excel file in AWS S3.
So far what i have achieved is :
I am able to get data from database and convert it to memory stream. I have written another API to receive this stream. But couldn't manage to get to pass memory stream from one API to another API.
1st API :
public async Task<ICollection<UserDTO>> ExportUsers(Guid groupId, HttpRequestMessage request)
{
var ms = // get's memory stream out of data received from database.
var client = new HttpClient
{
BaseAddress = new Uri("http://localhost:58025/")
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/bson"));
MediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
//Not sure about BsonMediaTypeFormmater. Juz gave it a try
var response = await client.PostAsync("http://localhost:58025/Resource/Memory", ms, bsonFormatter);
}
2nd API :
[HttpPost]
[Route("Resource/Memory", Name = "UploadMemory")]
public async Task<IHttpActionResult> UploadMemoryFile(MemoryStream memory)
{
// Not reaching until here
}
Any help is highly appreciated!!

Related

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)

WCF / ASP.NET MVC MessagebodyStream to Memory or Filestream

I have a ASP.NET MVC Website as Frontend that is connected via WCF (net.tcp streamed response) to a backend running on a different server.
The Backendservice implements a servicecontract that contains the follwoing method
[ServiceContract]
public interface BackendService
{
[OperationContract]
Stream GetDownload(int dataId);
}
The service is hosted with the transfermode as streamed Response.
At the frontend I want to offer the ability to Download the file that is streamed from the Backend.
Because the MessageBodyStream returned from the WCFChannel can't be converted automatically to a Filestream and actionresult I tried to convert it to a Memorystream. So I had to read the full MessageBodyStream and copy it to an Memorystream, that can be returned in an Actionresult as FileStreamResult.
public class MyAspNETMVCController:Controller
{
public FileStreamResult DownloadFile(int DataId)
{
var stream = new MemoryStream();
var netstream = downloadService.GetDownload(rawDataId);
netstream.CopyTo(stream);
stream.Position = 0;
return new FileStreamResult(stream, "application/zip");
}
}
The Files a try to offer are about 4GB and sometimes I get a OutOfMemory Exception. Is there any "nice" way of getting big data from an WCF streaming service and return them as FileStreamResult to the Client?
I do not want a direct connection between the client and the Backend. The complete communication should run over the ASP.NET MVC Website.

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.

How to manage byte[] params between applications with WebApi

I have a controller (ApiController) which is ready to receive an XML as a parameter. One of its node is a byte[] (document) This service is built in .Net but another company is going to use my service from Java platform.
We want to avoid that the service in .Net becomes blocked by receiving many request from Java application(this must be asynchronous) So the Java application can send us multiple request with the xml which contains the byte[] node. I don't know how the Java application must manage this call but in .net we want to continue being always available.
I've been reading the new async and await keywords and I not very sure if it must apply to my service on my controller.
My controller looks like this currently:
public class MyController : ApiController
[HttpPost, ActionName("myMethod")]
public void MyMethod(HttpRequestMessage request)
{
XmlDocument doc = new XmlDocument();
doc.Load(request.Content.ReadAsStreamAsync().Result);
//do something...
//call method to transform byte[] to physical file and save it
}
and I've been testing from another application (client) in .Net like this:
private void button1_Click(object sender, EventArgs e)
{
TestMethod();
}
public async Task TestMethod()
{
string xml = "<root> .......";
var content = new StringContent(xml, Encoding.Unicode);
var client = new HttpClient();
HttpResponseMessage result = await client.PostAsync("http://localhost:port/api/myController/myMethod", content);
}
It works fine. I mean click many times on the same button and it creates my file correctly with a little delay (physically) because the file size but the client application it never gets blocked. But I'm not very sure if the client must run this asynchronously or the service must be prepared to do it by itself and the client from Java must only do the request through http.
Or even, I must do the conversion of the file from byte[] to physical file async?
Each request made to your api will get a new instance of your controller and its own thread, so you don't need to worry about the conversion of your byte[] to a file and the saving of that file blocking incoming requests.
A reference to this can be found here: http://blogs.msdn.com/b/roncain/archive/2012/07/16/dependency-injection-with-asp-net-web-api-and-autofac.aspx

Categories

Resources