Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewComponents in Areas

I may be doing this wrong (I cannot find any documentation on how to do it any other way). When you create a ViewComponent in an Area, the Search paths are incorrect:

namespace HelloWorld
{
    [Area("Test")]
    public class HelloViewComponent : ViewComponent
    {
        public IViewComponentResult Invoke()
        {
            return View();
        }
    }
}

Instead of searching for the view at /Areas/Test/Views/Components/Hello/Default.cshtml the following exception is thrown:

InvalidOperationException: The view 'Components/Hello/Default' was not found. The following locations were searched:
/Views/Home/Components/Hello/Default.cshtml
/Views/Shared/Components/Hello/Default.cshtml.

I am invoking the view by doing the following: (in /Views/Home/Index.cshtml)

@Component.Invoke("Hello")

There does not seem to be a way to include an area to invoke the view from.

Any ideas on either the correct way to invoke a ViewComponent from within an Area or if the above is incorrect and I am making a mistake.

https://github.com/aspnet/Mvc/issues/2640

like image 799
logikal Avatar asked Jun 02 '15 01:06

logikal


Video Answer


3 Answers

The Area attribute can only be used with controllers. When you make a request to a view within an area and if this view has any view components referenced in them, then MVC looks for the view component's views in certain order.
Following is the difference in how a view component view is searched when a request matches an area based controller vs. a non-area controller.

Example:

  1. View Component's view search path for a request like /Admin/Home/Index where Admin is an area.

    • /Areas/Admin/Views/Home/Components/Products/Default.cshtml
    • /Areas/Admin/Views/Shared/Components/Products/Default.cshtml
    • /Views/Shared/Components/Products/Default.cshtml.
  2. View Component's view search path for a request like /Home/Index (non-area request)

    • /Views/Home/Components/Products/Default.cshtml
    • /Views/Shared/Components/Products/Default.cshtml.
like image 70
Kiran Avatar answered Oct 01 '22 04:10

Kiran


The ViewComponents files should be placed as below:

ViewComponent in MVC Area

Then invoke from the View:

@await Component.InvokeAsync(typeof(Swastika.Web.Start.Areas.Portal.ViewComponents.MainSidebar));

This works for me. I hope it helps!

like image 36
Smilefounder Avatar answered Oct 01 '22 03:10

Smilefounder


When using your component you should be able to use absolute path to your view like this View("~/Areas/Test/Views/Components/Hello/Default.cshtml") to fix your problem.

like image 26
Wanton Avatar answered Oct 01 '22 04:10

Wanton