4

I am beginner for asp.net core. I am building file conversion website. PNG to JPG, PDF to Word etc.. In there I amusing fileuplaod control to upload content for the conversation. Instead using same control on every view I thought put this control in one class and call them. When I search internet I found following two methods

  1. ViewComponent method
  2. Partial view method

Now I am confused what to use? Note that on page to page upload file type will be differ. on JPG to PNG converter page I have to restrict the fileuplaod control to only use JPEG images. So I want to pass some parameters to this common control and after Upload process done, I want to call back to the calling page to do specific convertions.

So following things I have implemented so far

I followed Viewcomponentmethod

@model BassModel
@*<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="@Model" accept="image/*" /></div>
        <br />
    </div>
    <br />
    <input asp-action="Index" type="button" value="Upload" class="btn btn-primary" />
    <input asp-action="Clear" type="submit" value="Clear" class="btn btn-outline-primary" />
    <br />
@*</form>*@

On PDF to word view

<form asp-controller="FileUploadController">
    @section _FileUpload{
        @await Component.InvokeAsync("_FileUpload", Model)
    }
</form>

On _layout page

<div class="container">
    <div class="row">
        <div class="col-md-7">
            <div class="container background_color_white">
                <main role="main" class="pb-3">
                    @RenderBody()
                </main>
            </div>
            <br />
            <div class="container background_color_white">
                @RenderSection("_FileUpload",false)
            </div>
        </div>
</div>

So far I done this. Erros are coming. But before I go further, I want to ensure what I do is right. Am I going in the right direction?

1 Answer 1

6

Instead using same control on every view I thought put this control in one class and call them. When I search internet I found following two methods

ViewComponent method

Partial view method

Now I am confused what to use?

Well, based on your scenario, let's have a look in which context we should better use partial views

  1. If you want to split your larger mark up files
  2. You want to reduce redundant file accross your projct.

Note: As per Microsoft recomendation, we shouldn't use a partial view where complex rendering logic or code execution is required to render the markup. Instead of a partial view, use a view component. You could check here.

However, based on scenario it has appeared that you don't want to use same control everywhere and you have complex logical implementation within your project, here we goes the crucial reasons why we should use View components

Although both partial views and View components are similar but View component is more robust and can handle complex requiremnet as it depend on the data passed while calling which completely comply with your requirement.

Demo implementation of your scenario:

It would be nicer if could share your error details what you are up to now. Nonetheless, Based on your shared snippet I have tried to simulate a quick demo for you based on the scenario:

Component Model:

public class UploadComponentModel
    {
        public IFormFile? MyUploadedFile { get; set; } = null;
        public string? FileExtntionName { get; set; } = string.Empty;
        public string? UploadedFileName { get; set; } = string.Empty;
    }

View Component Class & Directory:

    [ViewComponent(Name = "FileUploader")]
    public class FileUploaderViewComponent : ViewComponent
    {

        public IViewComponentResult Invoke(UploadComponentModel filUploadViewModel)
        {
            return View("FileUploader", filUploadViewModel);
        }
    }

enter image description here

View Component cshtml in Shared Folder:

@model DotNet6MVCWebApp.Models.UploadComponentModel
<div class="col-sm-4">
    <div class="card" style="width: 18rem; margin-bottom:20px;box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;">
        <div class="card-body">
            <form asp-controller="FileUploadViewComponent" asp-action="Index" enctype="multipart/form-data">
                <div class="card card-body">
                    <strong>Select PDF file to convert</strong> <div id="chooseFile"><input type="file" asp-for="MyUploadedFile" accept="image/*" /></div>
                    <br />
                </div>
                <br />
                <input type="submit" value="Upload" class="btn btn-primary" />
                <input asp-action="Clear" type="submit" value="Clear" class="btn btn-outline-primary" />
                <br />
                <label asp-for="FileExtntionName" class="control-label">@Model.FileExtntionName</label>
                <br />
                <label asp-for="UploadedFileName" class="control-label">@Model.UploadedFileName</label>
            </form>
        </div>
    </div>

</div>

enter image description here

Controller:

public class FileUploadViewComponentController : Controller
    {
        public IActionResult Index(UploadComponentModel FileName)
        {

            var uploadedFileDetails = new UploadComponentModel();
            if (FileName.MyUploadedFile == null)
            {
                return View(uploadedFileDetails);
            }
            else
            {
                string checkFileExtension = System.IO.Path.GetExtension(FileName.MyUploadedFile.FileName);

             
                uploadedFileDetails.MyUploadedFile = FileName.MyUploadedFile;
                uploadedFileDetails.FileExtntionName = checkFileExtension;
                uploadedFileDetails.UploadedFileName = FileName.MyUploadedFile.FileName;
                return View(uploadedFileDetails);
            }
         
        }
    }

Note: Here you can check for your desired file extension and set conditional logic based on your requirement and finally pass the model which will pass through the component.

Check File Type:

               string[] expectedFile = { ".pdf", ".png", ".jpeg" };

                if (expectedFile.Contains(checkFileExtension))
                {
                    uploadedFileDetails.FileExtentionMessage = "Right extension uploaded";
                }

Invoke View Component In View:

@model DotNet6MVCWebApp.Models.UploadComponentModel
<div>

    @await Component.InvokeAsync("FileUploader",Model)
</div>

Note: This is only for demo purpose to assist you to get rid of your error and simulate a imaginary implementation of your scenario.

Output:

enter image description here

Note: If you still interested to know more details on View components you could check our official document here

Sign up to request clarification or add additional context in comments.

5 Comments

Wow Mr Farid. Thank you very much for your time composing this answer. This is super duper helpful. Please keep doing this. You have no idea how this helped me. Thanks again.
Can I get the result of the file-upload control's variable back to the controller? (For eg: Uploaded file location) In my current implementation, execution end from the view component
Thanks for your feedback and glad to asist you. Yes you can the response back to the file as well, infact, In my capture, I have shared that as well. As the answer already larger in size so I wouldn't modify this part. If you encounter any challenges, you can ask question, I will try to explain.
Imagine there is a file upload button inside this view component. After file upload into a specific location I want to redirect to a page called Download and in there I need to find that file and download. I cannot find resources to redirect from viewcomponent to a view.
Actually, is beyond view componet's responsibility because is class dependent you directly cannot response back to somewhere. You haven't share this scenario before otherthan, I woundn't suggest you viewcomponent. Why don't you use view and controller directly as you need redirection twice. As a work around, once file uploaded then return file path and download link back to viewcomponet apply taghelper to redirect to your download controller or anything you have. I can help with example if you have new question on it but we need additional viewcomponent or action for that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.