2

Using asp.net core MVC application here. I have my areas defined and routing works as expected.

One thing i would like to do, is have a fallback route in case the area does not exist.

I have the following structure:

APP
-- Areas
   -- SharedArea
      -- Controllers
         -- LoginController
         -- UserController
         -- AnotherController
         -- AndSoOnController
   -- SomeArea1
      -- Controllers
         -- HomeController
   -- SomeArea2
      -- Controllers
         -- HomeController
         -- LoginController

My ultimate goal, is to have shared controllers that is being used as a fallback in the event that an area does not have the specified controller.

Scenario 1

User currently browse SomeArea1 and clicks on Login. There is no LoginController for SomeArea1 and he gets directed to SharedArea\Login.

Scenario 2

User currently browse SomeArea2 and clicks on Login. There is aLoginController for SomeArea2 and he gets directed to SomeArea2\Login.

How would one go about configuring your routes in the Startup.cs file?

My current route setup in startup.cs:

app.UseMvc(routes =>
        {
            routes.DefaultHandler = areaRouter;
            routes.MapRoute("areaRoute", "{area:exists}/{controller=Home}/{action=Index}/{id?}");
            routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
        });

areaRouter is a custom implimentation for subdomain routing, you can view more here: subdomain routing to areas

stoic
  • 4,700
  • 13
  • 58
  • 88

1 Answers1

2

One thing i would like to do, is have a fallback route in case the area does not exist.

Implement the base controllers for each area. In this way the controllers from those areas will use the HandleAttribute from the base controller. It's only 1 setting (one for each area in fact)

Scenario1: Create a base(shared) Controller in your area:

[Authorize(ActiveAuthenticationSchemes = "sharedarea")]//see solution for next scenario
public class SharedAreaController : Controller
{
    [AllowAnonymous]
    public login()
    {

    }
}

Derive SomeArea1 controllers from this controller:

public class HomeController : SharedAreaController 
{
    // actions for this controller
}

Scenario2: The place where you register you CookieAuthentication middleware, do this:

app.UseCookieAuthentication(o =>
{
    o.LoginPath = "/SomeArea2/login";
    o.AuthenticationScheme = "SomeArea2";
    //TODO: set other interesting properties if you want to
});

then On you controller/action, specify the authentication scheme like:

[Authorize(ActiveAuthenticationSchemes = "SomeArea2")]
public IActionResult PageWhichNeedsArea2Auth()
{
    return Content("sth");
}

I hope to be helpful :)

Amirhossein Mehrvarzi
  • 18,024
  • 7
  • 45
  • 70
  • Hey man, i did not implement your solution, but a base controller with overridable action results did the trick for me. I still have to add the controller in each area, but i can just choose to override the actions that i want to. Thanx for pointing me in the right direction – stoic Aug 02 '17 at 10:05