logikal
logikal

Reputation: 1141

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

Upvotes: 12

Views: 5498

Answers (3)

Smilefounder
Smilefounder

Reputation: 599

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!

Upvotes: 7

Wanton
Wanton

Reputation: 840

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.

Upvotes: 5

Kiran
Kiran

Reputation: 57999

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.

Upvotes: 8

Related Questions