MVC ASP-NET Core. Views and Controllers within subdirectories

0

I am developing an application in ASP.NET Core MVC and I have some questions regarding the structure of the controllers and views. In summary, the application has the same structure for two types of users, Company and Investor.

The application detects what kind of user has been logged in and changes the menu links to the Company/[controller]/[action] or Investor/[controller]/[action]

format

The directory structure is as follows:

Image structure of directories

The controllers have the following routing label that works well:

[Route("/Company/[controller]/[action]")]
public class DashboardController : Controller
{...

I'm having problems with the views, which have the same directory structure, since it does not detect the corresponding view. I have to put in each Action a return View("Views/Company/Dashboard/Dashboard.cshtml") with the entire route to the view and that smells bad. The same thing happens with views that have partial renders to other views in the same subdirectory.

Example: Company/Dashboard/Dashboard.cshtml contains:

<partial name="Users" />

Where Users.cshtml is a view in the same directory q Dashboard.cshtml

InvalidOperationException: The partial view 'Users' was not found. The following locations were searched:
/Views/Dashboard/Users.cshtml
/Views/Shared/Users.cshtml
/Pages/Shared/Users.cshtml

Is this the best way to structure an application with these characteristics?

Is there any way to tell MVC to use another route for the views?

Thank you.

EDITED:

One solution is to add a class that implements IViewLocationExpander

   public class ViewLocationExpander : IViewLocationExpander
    {
        public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
        {
            string[] locations = new[] 
            {
                "/Views/Company/{1}/{0}.cshtml",
                "/Views/Investor/{1}/{0}.cshtml",
                "/Views/Shared/{0}.cshtml"
            };

            return locations.Union(viewLocations);
        }

        public void PopulateValues(ViewLocationExpanderContext context)
        {
            context.Values["customviewlocation"] = nameof(ViewLocationExpander); 
        }
    }

And register it with ...

services.Configure<RazorViewEngineOptions>(options =>
            {
                options.ViewLocationExpanders.Add(new ViewLocationExpander());
            });

Now the application detects the view well BUT always selects the first one in case I enter as a Company or as an Investor, and the menu has no way of indicating one or the other Controller

Is there any way to indicate it?

                <li><a asp-controller="Dashboard" asp-action="Index">Company Dashboard</a></li>
                <li><a asp-controller="Dashboard" asp-action="Index">Investor Dashboard</a></li>
    
asked by JotaStar 12.09.2018 в 17:46
source

1 answer

0

If the content depends on the profile but the template and the logic is the same then you do not have to repeat the code anywhere.

The correct thing is that in the controller questions about the role of the user and based on that you modify the logic, even inside the controller you can change the view to use depending on the profile.

Keep in mind that one thing is the path to the 'endpoint' and another thing is the view you render,

In each controller you can do something to set your own view you want to render, and this is completely independent of the Route you use to invoke the endpoint (Controller)

return View("~/Views/Wherever/SomeDir/MyView.aspx");
    
answered by 03.10.2018 в 19:45