Royi Namir
Royi Namir

Reputation: 148524

ASP.NET's Conditional bundling - real world implementation?

I have many levels of user permissions in my site.

So a junior user can NOT do things that a senior user can do. ( there are many levels of users. senior vs junior is just for simplification).

In addition to a server side validation for who is the user and what he can/t do — I also want NOT to provide the Javascript function registration at first place . (So if a user is a junior user , then his JS files should not contain JS functions of a senior user.)

Example :

The site has a general add javascript function which should appear to all users:

function add() {
    console.log("Add");
}

Junior users has higher privilege so they can ALSO do subtract . so their JS files include the subtract method:

function substract() {
    console.log("substract");
}

A general users won't have this substract method

Senior users has higher privilege so they can ALSO do power. so their JS files include the power method :

function power() {
    console.log("power");
}

A senior user won't have this power method

OK

According to this answer :

Note that you must have a separate bundle per page. You should not modify one and the same bundle on the fly....etc...

So , I created ( for now) 2 bundles , one for each page :

bundles.Add(new ScriptBundle("~page1Junior").Include(
                      "~/Scripts/General.js", "~/Scripts/Junior.js"));

bundles.Add(new ScriptBundle("~page1Senior").Include(
                      "~/Scripts/General.js", "~/Scripts/Senior.js"));

And then I take the relevant bundle according to some login and use :

<script src='@Scripts.Url("~/page1Senior (or) Junior")' async> </script>

Question

This seems like a wrong way to go.

If I have 10 pages and 10 user levels , According to that approach , I will need 100 different bundles.

what is the right way of serving appropriate js files for their relevant user permissions ?

Pseudo code of what i'm after :

user level       js files(combined to one)
------------|-------------
    1            [a,b]
    2            [a,b,c]
    3            [a,b,c,d]
    4            [a,b,c,d,e]

So If a user level 3 is logged on , then a single abcd.js JS file should be served ( minified).

Upvotes: 1

Views: 566

Answers (1)

Dandy
Dandy

Reputation: 2177

One way is to use DynamicBundleFolder

If you can have a directory structure like

Scrtips
-- /Permissions
   -- /1
      -- a.js
      -- b.js
   -- /2
      -- a.js
      -- b.js
      -- c.js
   -- /3
      -- c.js
      -- d.js

where 1,2,3 are the restriction levels, then in your RegisterBundles add a DynamicBundle

bundles.Add(new DynamicFolderBundle("userScripts", "*.js",new JsMinify()));

And then in your _layout.cshtml, you can do

@{
    var userPermissionLevel = 2; // grab your user permission level, from session maybe
}

@Scripts.Render("~/Scripts/Permissions/"+ @userPermissionLevel +"/userScripts")

and that will render all the scripts in that directory. You dont have to create bundles for each page then. And if you need to add new permission based file, just add to respective permission folder.

Update: This will work fine if you have unique js files for each permission level. For shared files, updating them will be quite a work. So what you can do is create bundle according to permission levels like

    // Bundle for permission level 1
    bundles.Add(new ScriptBundle("~/bundles/permissions/1").Include(
                            "~/Scripts/a.js")
                            .Include("b.js"));

    // Bundle for permission level 2
    bundles.Add(new ScriptBundle("~/bundles/permissions/2").Include(
                            "~/Scripts/b.js")
                            .Include("c.js"));

   // and so on for each level 3,4,5 include specific level files

and then again you can add them to page throught _layout.cshtml

@{
   var userPermissionLevel = 2; // grab your user permission level, from session maybe
 }

@Scripts.Render("~/bundles/permissions/"+userPermissionLevel)

Upvotes: 3

Related Questions