Getting the zero byte in the PutFile method in request body - asp.net-core-mvc

We are getting the zero byte in the PutFile method in request body, but we can do the online editing of document and it is reflecting in other browsers as well (if we are editing the file in two browsers at same time ).
We are using ASP.Net Core and we are reading the request body like -
var bytes = new byte[context.Request.Body.Length];
context.Request.Body.Read(bytes, 0, bytes.Length);
Can anyone please help us on this one?

I solved this problem by using following code -
byte[] bytes;
context.Request.Body.Seek(0, SeekOrigin.Begin);
using (MemoryStream memoryStream = new MemoryStream())
{
context.Request.Body.CopyTo(memoryStream);
bytes = memoryStream.ToArray();
}

Related

Unable to download PDF file, fetched from Sql Database.Bytes value has been fetched, Function doesn't through any error, But PDF is not downloaded

I am unable to download a PDF file, fetched from Sql Database. Bytes value has been fetched, Function doesn't throw any error, but the PDF is not downloaded.
Code:
public ActionResult PrintPDF(string projectSelection)
{
byte[] extract = (byte[])_selectionManager.FindPdf();
MemoryStream pdfStream = new MemoryStream();
pdfStream.Write(extract, 0, extract.Length);
pdfStream.Position = 0;
HttpContext.Response.AddHeader("content-disposition",
"attachment; filename=form.pdf");
return new FileStreamResult(pdfStream, "application/pdf");
}
Since you already have the file content as bytes, why converting it to stream ?
Please check if this works
byte[] extract = (byte[])_selectionManager.FindPdf();
return File(
extract, System.Net.Mime.MediaTypeNames.Application.Pdf, "form.pdf");

Using WebAPI to stream MJPEG always buffers

I'm using HttpSelfHostConfiguration to create a WebAPI (service). My goal is to have one route stream the mjpeg video from a security feed and have other routes available for configuration and the web interface.
The issue I'm having is that every example I've come across expects a known quantity of images in order to set the content-length for the main response. I don't have this, and flushing the stream doesn't do anything.
Here's the current code for the response. If I use this same code with raw sockets instead of through an ApiController, I can stream it just fine, but creating a webserver from scratch for everything else I'm needing doesn't seem like a lot of fun.
[HttpGet]
public HttpResponseMessage Stream(int channel)
{
var response = Request.CreateResponse();
response.Content = new PushStreamContent((outputStream, content, context) =>
{
StreamWriter writer = new StreamWriter(outputStream);
while (true)
{
using (MemoryStream ms = new MemoryStream())
{
ReadMemoryMappedFile(channel);
ms.SetLength(0);
this.Image.Bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] buffer = ms.GetBuffer();
writer.WriteLine("--boundary");
writer.WriteLine("Content-Type: image/jpeg");
writer.WriteLine(string.Format("Content-length: {0}", buffer.Length));
writer.WriteLine();
writer.Write(buffer);
writer.Flush();
}
}
});
response.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("multipart/x-mixed-replace; boundary=--boundary");
return response;
}
I hope my late answer will help, since I ran into the same issue recently and it took me some time to figure it out...
My solution was to specify the boudary int the ContentType without the "--" (but you need to keep them while writing in the stream).
Try to configure the Headers like that :
response.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("multipart/x-mixed-replace; boundary=boundary");
And write boundaries in the stream like that :
writer.WriteLine("--boundary");
Like this it works for me.
I couldn't find anywhere that explicitly states this, but I'm going to assume that HttpSelfHostConfiguration does not support the functionality I'm looking for, and always requires the stream to be closed before it will release the buffer.
I swapped HttpSelfHostConfiguration with OWIN.SelfHost and it works as expected.

What is the alternative for HttpContext.Response.OutputStream to use in WebAPI's HttpResponseMessage

I'm writing a WebAPI for handling PDF documents. It was written in a ashx page earlier implementing IHttpHandler and getting the context using HttpContext. I'm now writing it using WebAPI. In WebAPI we have HttpResponseMessage. For HttpContext.Response.BinaryWrite we have new ByteArrayContent in HttpResponseMessage. But what is the alternative for HttpContext.Response.OutputStream in WebAPI? I need to have the alternative of OutputStram in WebAPI because im passing this OutputStream as a parameter to another dll.
Code in ashx:
SomeReport.PdfReport rpt = new SomeReport.PdfReport(docID);
rpt.CreateReport(context.Response.OutputStream);
Actually you can use any stream for example MemoryStream but result should be wrapped into StreamContent.
public HttpResponseMessage Get()
{
var response = Request.CreateResponse();
var outputStream = new MemoryStream();
//write data to output stream
//or passing it to somewhere
outputStream.WriteByte(83);
outputStream.Position = 0;
response.Content = new StreamContent(outputStream);
return response;
}
If you need direct writing to output stream, please consider using PushStreamContent. Example

Web API - Setting Response.Content with byte[] / MemoryStream Contents not working properly

My requirement is to use Web API to send across the network, a zip file (consisting a bunch of files in turn) which should not be written anywhere locally (not written anywhere on the server/client disk). For zipping, I am using DotNetZip - Ionic.Zip.dll
Code at Server:
public async Task<IHttpActionResult> GenerateZip(Dictionary<string, StringBuilder> fileList)
{
// fileList is actually a dictionary of “FileName”,”FileContent”
byte[] data;
using (ZipFile zip = new ZipFile())
{
foreach (var item in filelist.ToArray())
{
zip.AddEntry(item.Key, item.Value.ToString());
}
using (MemoryStream ms = new MemoryStream())
{
zip.Save(ms);
data = ms.ToArray();
}
}
var result = new HttpResponseMessage(HttpStatusCode.OK);
MemoryStream streams = new MemoryStream(data);
//, 0, data.Length-1, true, false);
streams.Position = 0;
//Encoding UTFEncode = new UTF8Encoding();
//string res = UTFEncode.GetString(data);
//result.Content = new StringContent(res, Encoding.UTF8, "application/zip");
<result.Content = new StreamContent(streams);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
//result.Content.Headers.ContentLength = data.Length;
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "test.zip";
return this.Ok(result);
}
The issue I am facing is that after the zip file downloaded at client end when modified as a test.bin has its stream contents (byte[] data in this example’s contents) missing. (I am getting back a test.zip file. When I change the file locally from test.zip to test.bin, I am seeing that the File’s contents as shown below. It does not contain the Response.Content values. P.S. I have also tried the MIME type “application/octet-stream” as well. No luck!)
Test.zip aka test.bin’s contents:
{"version":{"major":1,"minor":1,"build":-1,"revision":-1,"majorRevision":-1,"minorRevision":-1},
"content":{"headers":[{"key":"Content-Type","value":["application/zip"]},
{"key":"Content-Disposition","value":["attachment; filename=test.zip"]}]},
"statusCode":200,"reasonPhrase":"OK","headers":[],"isSuccessStatusCode":true}
Can someone please help me on how we can set result.Content with a MemoryStream object (I have seen example of “FileStream” at other places on google to set “result.Content” but I want to use MemoryStream object only!). I am highlighting this because I think the problem lies with setting the MemoryStream object to the result.Content (in order to properly save the streams content into the result.Content object)
P.S. I have also gone thru Uploading/Downloading Byte Arrays with AngularJS and ASP.NET Web API (and a bunch of other links) but it did not help me much… :(
Any help is greatly appreciated. Thanks a lot in advance :)
I got my issue solved!!
All I did was to change the Response Type to HttpResponseMessage and use "return result" in the last line rather than Ok(result) { i.e. HttpResponseMessage Type rather than OKNegiotatedContentResult Type)

MVC. Itextsharp write pdf to response

I am generating pdf using itexsharp.
I am creating MemoryStream, then when i am trying t write MemoryStream bytes in to response but no luck. When i am executing this code in my controller the pdf not coming in response. Memory stream is populaitng correctly i can see this in debugger, but for some reason this number of butes not coming in response.
Here is my code:
HttpContext.Current.Response.ContentType = "application/pdf";
...
using (Stream inputPdfStream = new FileStream(pdfFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream outputPdfStream = new MemoryStream())
{
PdfReader reader = new PdfReader(inputPdfStream);
PdfStamper stamper = new PdfStamper(reader, outputPdfStream);
....
//try one
outputPdfStream.WriteTo(HttpContext.Current.Response.OutputStream); // NOT POPULATING Response
//try two
HttpContext.Current.Response.BinaryWrite(outputPdfStream.ToArray()); // NOT POPULATING Response Too
HttpContext.Current.Response.End();
}
May be some one have any ideas?
Could you not use
Response.ContentType = "application/pdf"
Response.AddHeader("Content-Type", "application/pdf")
Response.WriteFile(pdfFilePath)
Response.End()
You should use the FileContentResult Controller.File(byte[] content, string contentType) method:
public ActionResult GeneratePDF()
{
var outputStream = new MemoryStream(); // This will hold the pdf you want to send in the response
/*
* ... code here to create the pdf in the outputStrem
*/
return File(outputStream.ToArray(), "application/pdf");
}
Source: Building PDFs in Asp.Net MVC 2.
Probably the memorystream is still set at the position after the last written byte. It will write all bytes from the current position (which is none). If you do a outputPdfStream.Seek(0) it will set the position back to the first byte, and will write the contents of the whole stream to the response output.
Anyway, like Dean says, you should just use the Reponse.WriteFile method.

Resources