Search code examples
asp.net-core-mvcasp.net-core-6.0

Rendering a ViewComponent on a Button's click from the controller in ASP.NET Core 6 MVC


Issue: I have been trying to render a view component on a button's click (in a view).

Approach: rendering a view component from a controller.

Issue: view component could not be found from the controller.

Error:

A view component named 'CommentViewComponent' could not be found.

View:

<form  asp-controller="Article" asp-action="InvokeViewComponent" method="post">
<table >
@foreach (var i in Model)
{
    <tr>
        <h3>This is post for the PostId:@i.Id</h3>
        <td>  @i.Title    </td>
        <td>  
            <button type="submit" id="Comment" >  </button>
        </td>
    </tr>
}
</table>

ArticleController (control came to controller's method):

public IActionResult InvokeViewComponent()
{
    return ViewComponent("CommentViewComponent", new { id=1 });
}

Problem: CommentViewComponent could not be found.

CommentViewComponent.cs file (location: Components\CommentViewComponent.cs):

namespace ViewComponentPartialView.Components
{
    public class CommentViewComponent:ViewComponent
    {
        public async Task<IViewComponentResult> InvokeAsync(int  id)
        {
            List<CommentViewModel> commentlist;

            HttpClient client = new HttpClient();

            var response = await client.GetAsync("URL");

            var jsondata = await response.Content.ReadAsStringAsync(); 
            commentlist = JsonConvert.DeserializeObject<List<CommentViewModel>>(jsondata);

            return View("~/Views/Components/_commentsofpost.cshtml", commentlist);
        }
    }
}

_CommentsofPost.cshtml (file location: Views\Components_CommentsofPost.cshtml):

@model IList<CommentViewModel>
<h4>Comments of each Postid Model </h4>
<div>
<h5>The number of comments : @Model.Count</h5>
</div>
<ul>
@foreach(var comment in Model)
{
    <li>@comment.PostId</li>
    <li>@comment.Id</li>
    <li>@comment.Name</li>
    <li>@comment.Email</li>
    <li>@comment.Body</li>
 }
 </ul> 

After resolving the issue - next question is: how and where to render the view component on the view (ArticleController's Index.cshtml).

I thought controller will call the view component, but it resulted in error.


Solution

  • Render the view component on the view is clearer.

    1 Create your viewcomponent

    public class SampleViewComponent : ViewComponent
    {
        public IViewComponentResult Invoke()
        {
            …
            return View();
        }
    }
    

    2 Create view for the View Component, By default it is located Views/Shared/Components/Sample/Default.cshtml

    3 Render it in your view

    @{
        ViewData["Title"] = "Home Page";
    }
    
    @* by tag-helper way *@
    <vc:Sample></vc:Sample>
    

    4 Remember to call the addtaghelper in your _ViewImports

    @addTagHelper *, YourProject
    

    enter image description here