Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi Tenant Razor pages

I am trying to set up Razor Pages routing to allow different views to be rendered for different tenants.

I have a directory structure as follows:

/Pages
    Test.cshtml.cs
    /Tenant1
        Test.cshtml
    /Tenant2
        Test.cshtml

Given I am already able to decide which tenant is required, how is it possible to configure the routing to map some path eg localhost:8080/Test to either Tenant1/Test or Tenant2/Test views.

like image 466
K.Amoa Avatar asked Jan 09 '19 10:01

K.Amoa


1 Answers

Use dynamic view content (via partial views).

With this solution, the Test page will dynamically load a different view depending on the route used to call it.

This means that you only have a single Test page but inside the cshtml file you will grab content from a partial view (more on that in a second).

First you will need to rename the files like so....

/Pages
    Test.cshtml.cs
    /Tenant1
        _Test.cshtml  // note it is prefixed with an underscore!
    /Tenant2
        _Test.cshtml  // prefixed with an underscore too.

The naming convention for a partial view is to prefix the file with an underscore (_). This will immediately identify to someone looking at your project files as a "non-routable" page.

Then you add a little bit of logic to render the partial views...

Test.cshtml

@{
    switch(...)  // used a switch statement to illustrate the solution
    {
        case "Tenant1":
            await Html.PartialAsync("~/Pages/Tenant1/_Test.cshtml");
            break;
        case "Tenant2":
            await Html.PartialAsync("~/Pages/Tenant2/_Test.cshtml");
            break;
        default:
            throw new NotImplementedException();
    }
}

You can read about partial views here.

Extra: Using the same page model.
I also noticed that you had wanted to use the same page model (meaning sharing Test.cshtml.cs for both. This is rather trivial, but for the sake of completeness of the answer here is how you would do that...

/Pages/Test.cshtml.cs

namespace Foo.Pages
{
    public class MySharedTestModel : PageModel
    {
        ...
    }
}

/Pages/Tenant1/Test.cshtml and /Pages/Tenant2/Test.cshtml

@page
@using Foo.Pages
@model MySharedTestModel 

...
like image 160
Svek Avatar answered Sep 22 '22 01:09

Svek