ASP WebAPI 2 _pdf HTTPResponseMessage_couldnt open - pdf

Used the below code to read a pdf file and return as response from WebAPI 2.
When I used a text file here and also changed the response FileName="new.txt", then it works fine. Running the WEBAPI in swagger, could download file in the response and the file opens too.
But if its a pdf file, the downloaded file couldnt be opened. Also tried zip and xl files....File is corrupted and couldnt be opened.
[HttpGet]
[Route("GetPDF")]
public IHttpActionResult GetABCPDF()
{
var bytes = System.IO.File.ReadAllBytes(bookPath_Pdf);
var dataStream = new MemoryStream(bytes);
HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(dataStream)
};
httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "new.pdf"
};
httpResponseMessage.Content.Headers.ContentLength = dataStream.Length;
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
ResponseMessageResult responseMessageResult = ResponseMessage(httpResponseMessage);
return responseMessageResult;
}

Related

AWS Lambda image/pdf upload to S3 is corrupted (asp.net core)

I have written a function that uploads a file in an s3 bucket. It works fine when I run my application locally.
But when I deploy the application in AWS Lambda, file upload is working properly but the file is being corrupted. The uploaded file size is a little bit higher than the actual file size.
txt file upload is working fine.
Here is my code
Guid guid = Guid.NewGuid();
string extension = System.IO.Path.GetExtension(logo.FileName);
var fileName = $"{guid}{extension}";
using (var ms = new System.IO.MemoryStream())
{
logo.CopyTo(ms);
ms.Position = 0;
System.IO.Stream stream = ms;
var client = new AmazonS3Client(AppConstants.S3AccessKey, AppConstants.S3SecretKey, Amazon.RegionEndpoint.USEast1);
PutObjectRequest putRequest = new PutObjectRequest
{
BucketName = AppConstants.S3Bucket,
Key = fileName,
InputStream = stream
};
PutObjectResponse response = await client.PutObjectAsync(putRequest);
}
I have configure API Gateway for binary data as well as change the LambdaEntryPoint with following code
RegisterResponseContentEncodingForContentType("multipart/form-data", ResponseContentEncoding.Base64);
Is there any other configuration that I missed?
I think you are not showing the full code you have written. I had the same issue yesterday.
I was using the System.Drawing.Image namespace to store the image and then I was resizing it. The problem with the System.Drawing.Image is that it is supported only on the Windows platform. That's why it was working from the local machine.
This is how I have solved this issue:
I had to install a third-party library called ImageSharp. The code is written below:
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Formats.Png;
public class Function
{
public MemoryStream GetReducedImage(int width, int height, MemoryStream resourceImage)
{
try
{
using (var image = Image.Load(resourceImage))
{
image.Mutate(x => x.Resize(width, height));
var ms = new MemoryStream();
image.Save(ms, new PngEncoder());
ms.Position = 0;
return ms;
}
}
catch (Exception e)
{
return null;
}
}
}

Download zip file

i have a zip folder in my wwwroot/files
how will i let the user download this file?
though about making a controller with something like this, but this is clearly wrong and it fails. It just does nothing even though it is reading the bytes and returning correctly
[HttpGet("DownloadOutput")]
public async Task<IActionResult> Invoice(string JobId)
{
string file = Directory.EnumerateFiles($"***PATH***\\{JobId}", "*.*",
SearchOption.AllDirectories)
.Where(n => Path.GetExtension(n) == ".zip").FirstOrDefault();
//converting file into bytes array
var dataBytes = System.IO.File.ReadAllBytes(file);
//adding bytes to memory stream
var dataStream = new MemoryStream(dataBytes);
HttpResponseMessage httpResponseMessage = new();
httpResponseMessage.Content = new StreamContent(dataStream);
httpResponseMessage.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
httpResponseMessage.Content.Headers.ContentDisposition.FileName = file;
httpResponseMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
return Ok(httpResponseMessage);
}
calling the file from my blazor code like this.
var result = await Http.GetAsync($"Inventer/DownloadOutput?jobId=JobId}");

how to get mime type of file in asp .net core

i am working with uploaded file preview in angular 8.. i have uploaded my files into local disc.. from there i need to get file content and preview.. I am able to preview pdf but only after converting to base64. I need to get mime type.. how to modify my method for that?
public IActionResult GetFileUploads(string filename)
{
List<FileUpload> obj = new List<FileUpload>();
foreach (string file in Directory.EnumerateFiles(#"D:\Uploads", "*", SearchOption.AllDirectories))
{
byte[] imageByteData = System.IO.File.ReadAllBytes(file);
string imageBase64Data = Convert.ToBase64String(imageByteData);
string imageDataURL = string.Format("data:image/png;base64,{0}", imageBase64Data);
FileUpload fileUpload = new FileUpload();
FileInfo fi = new FileInfo(file);
var fileName = fi.Name;
fileUpload.DocumentURL = imageDataURL;
fileUpload.DocumentName = fileName;
obj.Add(fileUpload);
}
return ReturnHttpOKResult(obj);
}

how to read excel file in memory (without saving it in disk) and return its content dotnet core

Im working on a webApi using dotnet core that takes the excel file from IFormFile and reads its content.Iam following the article
https://levelup.gitconnected.com/reading-an-excel-file-using-an-asp-net-core-mvc-application-2693545577db which is doing the same thing except that the file here is present on the server and mine will be provided by user.
here is the code:
public IActionResult Test(IFormFile file)
{
List<UserModel> users = new List<UserModel>();
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
using (var stream = System.IO.File.Open(file.FileName, FileMode.Open, FileAccess.Read))
{
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
while (reader.Read()) //Each row of the file
{
users.Add(new UserModel
{
Name = reader.GetValue(0).ToString(),
Email = reader.GetValue(1).ToString(),
Phone = reader.GetValue(2).ToString()
});
}
}
}
return Ok(users);
}
}
When system.IO tries to open the file, it could not find the path as the path is not present. How it is possible to either get the file path (that would vary based on user selection of file)? are there any other ways to make it possible.
PS: I dont want to upload the file on the server first, then read it.
You're using the file.FileName property, which refers to the file name the browser send. It's good to know, but not a real file on the server yet. You have to use the CopyTo(Stream) Method to access the data:
public IActionResult Test(IFormFile file)
{
List<UserModel> users = new List<UserModel>();
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
using (var stream = new MemoryStream())
{
file.CopyTo(stream);
stream.Position = 0;
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
while (reader.Read()) //Each row of the file
{
users.Add(new UserModel{Name = reader.GetValue(0).ToString(), Email = reader.GetValue(1).ToString(), Phone = reader.GetValue(2).ToString()});
}
}
}
return Ok(users);
}
Reference

download doc file in MVC

I have applicaiton which is the combination of MVC 4 + Web Api + SQL server.
I am trying to download the doc file to MVC but i have tried the below step.
I have Web API where i have written the below code. when i send the rowid it has the value stored in the DB as varbinary. file format can be any thing like .doc,pdf etc ... but however I am looking for the first doc or PDF file format.
When I call the Web api it will create the PDF file and download it , but the file is completely corrupted.
[ResponseType(typeof(MandateExceptionDO))]
[HttpGet]
[Route("api/DealingMandate/GetExceptionDoc/{rowId}")]
public HttpResponseMessage GetExceptionDoc(int rowId)
{
IDealingMandates repository = new DealingMandatesRepository();
List<MandateExceptionDO> mandateexceptiondoc =new List<MandateExceptionDO>();
mandateexceptiondoc = repository.GetExceptionDoc(rowId);
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
//response.Content = new ByteArrayContent(mandateexceptiondoc[0].Content);
//response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data");
//byte[] fileBytes = System.IO.File.ReadAllBytes(mandateexceptiondoc[0].Content);
response.Content = new ByteArrayContent(mandateexceptiondoc[0].Content);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "testing.pdf";
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
//return Ok(mandateexceptiondoc);
return response;
}
I am able to fix this issue on the web api i made the byte as string as show below
String doc = Convert.ToBase64String(customermandate.Content);
and for the MVC side i converted back to byte from the string
var doc = restClient.Execute(request);
var response = doc.Content.Substring(1, doc.Content.Length - 2).Replace(#"\/", "/");
byte[] docBytes = Convert.FromBase64String(response);
if (doc.Content != null && doc.Content.Length > 0 && !string.IsNullOrEmpty(doc.Content))
{
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename=" + FileName);
Response.BinaryWrite(docBytes);
Response.End();
}