How to register an area using app_start or webactivator?

I would like to avoid the call

AreaRegistration.RegisterAllAreas ()

in my global.asax because I'm trying to move all the startup logic into separate classes inside the App_Start folder. However, I was not successful at work. The first option tried to use this code:

[assembly: PreApplicationStartMethod(typeof(Startup), "PreInit")] namespace Foo { public class Startup {} } 

Where PreApplicationStartMethod comes from the System.Web namespace. In this case, the call to the registers is too early.

A second approach, based on this post by David Abbo , uses WebActivator: using System.Web.Mvc;

  [assembly: WebActivatorEx.PostApplicationStartMethod (typeof(AreaDemo.AreaConfig), "RegisterAreas")] namespace AreaDemo { public class AreaConfig { public static void RegisterAreas() { AreaRegistration.RegisterAllAreas(); } } } 

Unfortunately, despite the fact that no error was selected, an attempt to move to the area is not performed (as if registration had never occurred).

What is the correct way to register areas in ASP.NET MVC 5 from a startup class using the build directive rather than directly calling from Global.asax?

Update 1: Here is my registration area code:

 public class AdminAreaRegistration : AreaRegistration { public override string AreaName { get { return "Admin"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Admin_default", "Admin/{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new string[] { "AreaDemo.Areas.Admin.Controllers" } ); } } 

For some reason, the default values ​​are ignored, but the transition to / admin / home / index / 0./admin,/admin/home and / admin / home / index all 404 works.

+5
source share
1 answer

I believe this is a problem with the order (which, it seems, is what you suspect). I think that areas are registered after the Application_Start event, and therefore route routes are registered after non-terrestrial zone routes.

The reason the 4-segment URL ( /admin/home/index/123 ) works is because it cannot match the "default" for the MVC application. Thus, this route is skipped by default (since it matches only 1-, 2-, and 3-segment URLs), and routing will find a route specific to a specific area that can handle a 4-segment URL. A 1-, 2-, or 3-segment URL will correspond to a route without a zone, but, of course, there are no controllers outside the areas for processing such a URL, and therefore 404 is returned.

If I understood correctly, do you want regions to register after Application_Start , but before something else happens? Unfortunately, I do not know of any specific event to handle this. From IHttpModule you could try to process an event, such as BeginRequest , that happens very early, quickly register there only once (that is, do not register the material for each request!), And this should allow you to sneak before the ASP. NET Routing will do its stuff (which happens a bit later during PostResolveRequestCache ).

A complete alternative to this is to use attribute routes , which many people like because it can help avoid ordering problems.

0
source

Source: https://habr.com/ru/post/1204744/


All Articles