2

I want to be able to route to a different controller based on the domain name of the URL.

For example, when the request URL is www.domain1.com/requestpath or sub.domain1.com/requestpath, I want the routing to use Domain1Routing.

But if the request URL is www.domain2.com/requestpath or sub.domain2.com/requestpath, I want the routing to be handled by Domain2Routing.

The following code doesn't work. Do I need to specify the pattern differently? Or use different method than MapControllerRoute()?

app.UseRouting();

app.UseEndpoints(
    endpoints => {
      endpoints.MapControllerRoute(
          name: "Domain1Routing",
          pattern: "{subdomain}.domain1.com/{requestpath}",
          defaults: new { controller = "Domain1", action = "Index" }
      );
      endpoints.MapControllerRoute(
          name: "Domain2Routing",
          pattern: "{subdomain}.domain2.com/{requestpath}",
          defaults: new { controller = "Domain2", action = "Index" }
      );
    });
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
GratefulDisciple
  • 674
  • 8
  • 18
  • 1
    This doesn't address your question since you're looking ow to generalize these routes based on a hostname condition, but it's worth noting that you can at least _restrict_ routes to particular hostnames by using the [`RequireHost()`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.routingendpointconventionbuilderextensions.requirehost?view=aspnetcore-3.1) extension method. – Jeremy Caney Apr 23 '20 at 20:25
  • 1
    @JeremyCaney Thanks. I just discovered the same thing. Will write an answer for the solution that works for me. – GratefulDisciple Apr 23 '20 at 20:41

1 Answers1

4

As @JeremyCaney mentioned, what worked is using the RequireHost() extension method:

app.UseRouting();

app.UseEndpoints(
    endpoints => {
      endpoints.MapControllerRoute(
          name: "Domain1Routing",
          pattern: "{*requestpath}",
          defaults: new { controller = "Domain1", action = "Index" }.RequireHost("*.domain1.com");
      );
      endpoints.MapControllerRoute(
          name: "Domain2Routing",
          pattern: "{*requestpath}",
          defaults: new { controller = "Domain2", action = "Index" }.RequireHost("*.domain2.com");
      );
    });
GratefulDisciple
  • 674
  • 8
  • 18
  • 1
    I'm glad you were able to figure this out. Another option—which may be more elegant if you have a 1:1 mapping between hostnames:controllers—would be to use the new(er) [`[Host]` attribute](https://github.com/dotnet/aspnetcore/blob/master/src/Http/Routing/src/HostAttribute.cs). I've provided an example of both approaches on [my answer to a similar question](https://stackoverflow.com/a/61396547/3025856). – Jeremy Caney Apr 23 '20 at 21:25
  • 1
    @JeremyCaney problem with `HostAttribute` is that, AFAIK, you have to hard-code your domain names - I'd much prefer to be able to load them from config. – Cocowalla Sep 23 '21 at 11:33