2

To stop my application from getting cluttered I started working with areas. But now I always have to call:
http://localhost:49358/Document/Document/
instead of:
http://localhost:49358/Document/
How can I change my route to access the Controllers by name of the Area? (no HomeController)

I have the following folder structure inside of my Project:

Folderstructure inside my Project
The code for my route to the Areas looks like this:

routes.MapRoute(name: "areaRoute",template: "{area:exists}/{controller=Home}/{action=Index}");

And I placed the [Area("Document")] Tag in my DocumentController.

Edit:
As suggested by Shyju and Jamie Taylor I went with the HomeControllers. (Thank you both for the quick answers and explanations)

My Structure now looks like this and the routing is working like expected:
enter image description here

For me it's still a bit dissapointing to have so many HomeControllers and Index Files. Navigating code isn't that easy anymore:
enter image description here

Edit2:
After getting too annoyed with all those Homecontrollers, I went with the solution suggested by Jamie Taylor and rearanged everything in a Features folder. It needs a bit more configuration but is much cleaner in my opinion.
It is also further explained in this Microsoft Article (Just skip the Area stuff):
https://msdn.microsoft.com/en-us/magazine/mt763233.aspx

My structure now looks like this and routing works like a charm and the controller names are still meaningful:
enter image description here

Yush0
  • 1,547
  • 18
  • 22
  • I'm not sure that's what areas are for. Perhaps you should rethink your architecture. Perhaps you could add a razor page under the Document area which acts like an index page and provides all of the functionality of your Document Index view – Jamie Taylor Oct 12 '17 at 12:47
  • "Areas are an ASP.NET MVC feature used to organize related functionality into a group as a separate namespace (for routing) and folder structure (for views)" sounded promissing to me. What would you recommend otherwise? – Yush0 Oct 12 '17 at 12:50
  • You got there just before my edit was completed :P – Jamie Taylor Oct 12 '17 at 12:51

2 Answers2

2

The default route registration for areas use HomeController as the default value for the controller in the url. If you want DocumentController to be the default, update it in the StatrtUp class.

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "areas",
        template: "{area:exists}/{controller=Document}/{action=Index}/{id?}"
    );
});

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");

});

Keep in mind that that registration code is for all the existing areas (because we have {area:exists} in the url template), not just Document area. That means, Any time a request comes like yourApp\someAreaName, the framework will send the request to the index action of DocumentController in someAreaName.

You already organized your code related to documents to the Document area. Now why you need your controller name to be document ? I feel, it is repetitive.

I would personally rename the DocumentController inside the Document area to HomeController and use the default route registration code for the area registration ( which uses HomeController as the default controller value in the url template). This way, It will work for your future areas and your code looks more clean. IMHO, A HomeController in any area make sense where a DocumentController in any area will be confusing.

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "areas",
        template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
    );
});
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • Thank you very much for your response. I stumbled over this approach too. But this means for every new "Module" there will be a new entry in the startup.cs. I am trying to achiev something like: {area:exists}/{controller=}/{action=Index}/{id?} – Yush0 Oct 12 '17 at 12:52
  • Yes. That is why i recommended renaming your controller from Document to Home( you are already organized your code to the Document area, why repetitive name in controller now ? ) and use the default(Generic) registration code which should work for all new areas you create in future. – Shyju Oct 12 '17 at 12:55
2

I'm not sure that's what areas are for. Perhaps you should rethink your architecture.

In my ASP.NET MVC Core application template, I've leveraged Feature folders, which works a little like areas.

To do this, I've added the following to the ConfigureServices method:

serviceCollection.Configure<RazorViewEngineOptions>(options =>
{
  options.ViewLocationExpanders.Add(new FeatureLocationExpander());
});

Where FeatureLocationExpander is:

public class FeatureLocationExpander : IViewLocationExpander
{
  public void PopulateValues(ViewLocationExpanderContext context)
  {
  // Don't need anything here, but required by the interface
  }

  public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
  {
    // The old locations are /Views/{1}/{0}.cshtml and /Views/Shared/{0}.cshtml
    // where {1} is the controller and {0} is the name of the View

    // Replace /Views with /Features
    return new string[]
    {
      "/Api/{1}/{0}.cshtml",
      "/Features/{1}/{0}.cshtml",
      "/Features/Shared/{0}.cshtml"
    };
  }
}

Replacing the contents of the new string[] which is returned by ExpandViewLocations for your areas will mean that you won't have to add the routing attributes.

BUT, this does not fix your issue as that is not what areas are for.

Unless you added a razor page (named Index.cshtml) under the Documents area which acts as an index page for the Documents area. This Index.cshtml could provide all of the functionality of the Index.cshtml in your /Documents/Documents/Index.cshtml with the added bonus of having a code-behind like file (remember ASP.NET webforms?) which acts like your controller.

Jamie Taylor
  • 1,644
  • 1
  • 18
  • 42
  • Took me some fiddling but this is what I was looking for and clean way. Your example and this article helped me getting it going: https://msdn.microsoft.com/en-us/magazine/mt763233.aspx – Yush0 Oct 13 '17 at 14:16
  • I'm glad that I could help. – Jamie Taylor Oct 15 '17 at 17:06