I have a view component which do file upload.
public async Task<IViewComponentResult> InvokeAsync (ToolModel model)
{
if (!ModelState.IsValid)
{
return View();
}
if (model.FileUpload != null)
{
//SaveFullImage(strm, model.FileUpload.FileName);
#region Uploading photo]
string wwwPath = string.Empty;
string fromFileName = string.Empty;
string toFileName = string.Empty;
string fromFilePath = string.Empty;
string toFilePath = string.Empty;
if (model.FileUpload.Length > 0)
{
wwwPath = this.env.WebRootPath;
string guiD = Guid.NewGuid().ToString();
fromFileName = string.Format("{0}-{1}.{2}", DateTime.Now.ToString("yyyy-MM-dd"), guiD, model.FromFileType);
fromFilePath = string.Format("{0}\\file-uploads\\{1}", wwwPath, fromFileName);
toFileName = string.Format("{0}-{1}.{2}", DateTime.Now.ToString("yyyy-MM-dd"), guiD, model.ToFileType);
toFilePath = string.Format("{0}\\file-convertions\\{1}", wwwPath, toFileName);
try
{
using (Stream fileStream = new FileStream(fromFilePath, FileMode.Create))
{
await model.FileUpload.CopyToAsync(fileStream);
fileStream.Close();
}
}
catch (Exception)
{
throw;
}
}
var exists = System.IO.File.Exists(fromFilePath);
if (exists)
{
model.FromFileUploadedURL = fromFilePath;
model.ToFileConvertedURL = toFilePath;
model.IsSuccessFullFileUpload = true;
}
else
model.IsSuccessFullFileUpload = false;
#endregion
if (model.IsSuccessFullFileUpload)
{
FileConverters.ConvertPDFtoWord(model.FromFileUploadedURL, model.ToFileConvertedURL);
// Download Word file
//byte[] fileBytes = System.IO.File.ReadAllBytes(model.ToFileConvertedURL);
//return File(fileBytes, "application/force-download", "ddd");
}
}
return await Task.FromResult((IViewComponentResult)View(FullPathsOfViews.FileUpload, model));
}
At the end of the line
FileConverters.ConvertPDFtoWord(model.FromFileUploadedURL, model.ToFileConvertedURL);
After this I want to allow the converted doc file to downloaded back to user's PC. But below lines not work inside view component
byte[] fileBytes = System.IO.File.ReadAllBytes(model.ToFileConvertedURL);
return File(fileBytes, "application/force-download", "ddd");
Here is the action result from controller class.
public async Task<IActionResult> Index(ToolModel model)
How to do that? Because viewcomponent fired finally and it not comes back to the controller.
In Index.cshtml I added following code
@await Component.InvokeAsync("FileUpload",Model)
Below is my viewcomponent
<form asp-controller="FileUploadViewComponent" enctype="multipart/form-data">
<div class="card card-body">
<strong>Select PDF file to convert</strong> <div id="chooseFile"><input type="file" asp-for="FileUpload" accept="@Model.FileUploadFileFormats" /></div>
<br />
</div>
<br />
<input asp-action="Index" type="submit" value="Upload" class="btn btn-primary" />
<input asp-action="Clear" type="submit" value="Clear" class="btn btn-outline-primary" />
<br />
<canvas id="pdfViewer" style='width:350px;height:auto'></canvas>
</form>
I think you are still confused about view component features. We supposed not to do anything within InvokeAsync method. It will just act as and place holder what really a view component is. Rather we would be writing our conditional or any business logic either in viewcomponent caller controller or within viewcomponent.cshtml file but not InvokeAsync because it will beyond its scope. Even if we have written something within that's acually viewComponent developed for.
Instead of writting any business logic for downloading converted word file within view component, you ought to convert pdf to word file and save that in directory. Finally get the converted word file and pass it to your viewcomponent model.
When your model value passed back to your viewcomponent.cshtml now you can set downloading link or file name which will call the download controller. This would be the ideal scenario and this should be.
Let's take a look how we can do that in action:
Assuming we have below component for uploading .pdf file and after accomplishing all conversion process want .docx or downloadable link for word file as following:
Let's move towards the implementation:
Component Model:
Note: I as using DownloadLink where I would pass converted file name.
Component:
View Component cshtml:
Note: Write your business logic whatever in mind here. But you are doing instead which made the scenario complicated. Regarding the logic I have written is, at the beginning we woundn't have any file link so I am checking that and once we have file link and extension details only then showing the details link for download.
Download Controller Action:
Download View To Invoke View Component:
Download Docs File Controller Action:
Output: