I’m facing a problem downloading the file in Asp.Net core or maybe I’m not writing the right code.
I have an Asp.Net Core Web API with some methods to GetAllFiles, Upload, and Download files.
I’ve one method in my API’s controller to download the file(Code added below)
[HttpGet("{id}")]
public async Task<IActionResult> DownloadFile(Guid id)
{
var fileInDb = pdfRepository.GetByIdAsync(x=>x.Pdf_Pk == id, false);
if(fileInDb == null)
{
return NotFound();
}
//var fileName = _data.PdfDetail.Where(x => x.Pdf_Pk == id).Select(x => x.FileName).FirstOrDefault();
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "root\Files", fileInDb.Result.FileName);
var provider = new FileExtensionContentTypeProvider();
if(!provider.TryGetContentType(filePath, out var contentType))
{
contentType = "application/octet-stream";
}
var bytes = await System.IO.File.ReadAllBytesAsync(filePath);
return File(bytes, contentType, Path.GetFileName(filePath));
}
Here I’m returning the File.
I’m calling this method from my Web APP’s Controller.
Code for Download Method
public async Task<IActionResult> Download(Guid Id)
{
return RedirectToAction("Index" ,await PdfServices.DownloadAsync<ApiResponse>(Id));
}
Here PdfServices.DownloadAsync
is the service method, the code written below
public Task<T> DownloadAsync<T>(Guid Id)
{
return SendAsync<T>(new ApiRequest()
{
type = APIRequestHeader.APIRequest.ApiType.Get,
Data = Id,
Url = ApiUrl + "/api/PdfManager/"+Id
});
}
Now I’m calling this SendAsync Method which is used to send requests to API Methods and find the content, and I’m performing, serializing/deserializing here
public async Task<T> SendAsync<T>(ApiRequest request)
{
try
{
var client = httpClientFactory.CreateClient("PdfManager");
HttpRequestMessage message = new();
message.Headers.Add("Accept", "Applicaiton/Json");
message.RequestUri = new Uri(request.Url);
if(request.Data != null)
{
message.Content = new StringContent(JsonConvert.SerializeObject(request.Data), Encoding.UTF8, "Application/Json");
}
switch(request.type)
{
case APIRequest.ApiType.Post:
message.Method = HttpMethod.Post;
break;
case APIRequest.ApiType.Put:
message.Method = HttpMethod.Put;
break;
case APIRequest.ApiType.Delete:
message.Method = HttpMethod.Delete;
break;
default:
message.Method = HttpMethod.Get;
break;
}
HttpResponseMessage hrm = null;
hrm = await client.SendAsync(message);
var apiContent = await hrm.Content.ReadAsStringAsync();
if(true) //Don't know what to write in this, to download this file
{
var readByte = hrm.Content.ReadAsByteArrayAsync();
using(MemoryStream ms =new MemoryStream(readByte.Result))
{
var writer = new BinaryWriter(ms, Encoding.UTF8, false);
var res = new FileContentResult(readByte.Result, hrm.Content.Headers.ContentType.MediaType);
//return (T)res;
var test = JsonConvert.DeserializeObject<T>(res);
}
}
var apiResponse = JsonConvert.DeserializeObject<T>(apiContent);
return apiResponse;
}
catch(Exception ex)
{
var dto = new ApiResponse
{
ErrorMessage = new List<string> { Convert.ToString(ex.ToString())},
IsSuccess = false
};
var res = JsonConvert.SerializeObject(dto);
var ApiResponse = JsonConvert.DeserializeObject<T>(res);
return ApiResponse;
}
}
Now, Method will be used for all operations like GettingAllFiles, UploadingFiles, DeleatingFiles and Also DownloadFile.
Because we are returning the file from API’s Controller, Now how can I download that file
I’m not able to read Content as string
hrm.Content.ReadAsStringAsync();
because our content is not a string, it contains the files
If I read it as ByteArray then I’m not able to deserialize the object because it’ll ask for a type
How can I download this file coming into the Content from API’s controller?
how should I read it, what to return?