Sunday, 30 May 2010

Neat Routing Technique for Restricting Access to Tables

In answering this question “Table specific routing for insert not working” on the Dynamic Data Forum I came across a  way to restrict which tables the catch all routes in Dynamic Data processes, allowing you to specify routes that only allows List or Edit etc.

// Customers route
routes.Add("Customers", new DynamicDataRoute("{table}/{action}.aspx")
{
    Constraints = new RouteValueDictionary(new
    {
        action = "List",
        table = "Customers"
    }),
    Model = DefaultModel,
});

// Employees route
routes.Add("Employees", new DynamicDataRoute("{table}/{action}.aspx")
{
    Constraints = new RouteValueDictionary(new
    {
        action = "List|Edit",
        table = "Employees"
    }),
    Model = DefaultModel,
});

// Categories route
routes.Add("Categories", new DynamicDataRoute("{table}/{action}.aspx")
{
    Constraints = new RouteValueDictionary(new
    {
        action = "List|Details|Insert",
        table = "Categories"
    }),
    Model = DefaultModel,
});

// catch all route
routes.Add("CatchAll", new DynamicDataRoute("{table}/{action}.aspx")
{
    Constraints = new RouteValueDictionary(new
    {
        action = "List|Details|Edit|Insert",
        table = "^((?!Customers|Employees|Categories).)*$"
    }),
    Model = DefaultModel
});

Listing 1 – Filtering tables routes

In this sample I am specifying three custom routes for:

  1. “Customer” table to allow List action.
  2. “Employees” table to allow List and Edit actions;
  3. “Categories” table to allow List, Details and Insert actions;

To show that you can restrict any individual action or combination of actins.

Note: If you do not have a List action in the actions constraint then the table will not appear on the Default.aspx as there will be no list action and it will appear to be unscaffolded, this is not the case if you try a route that you have allowed i.e. Details or Insert then the specified routes will work, it will just not appear on the Default.aspx page.

But without filtering these tables out of the the “Catch All” route (Dynamic Data default route) the missing function will be available via through the “Catch All” route.

The solution is to add a Constraint that says don’t generate a route for these tables, we do this with a regular expression:

      "^((?!Customers|Employees|Categories).)*$"

the route value dictionary actually puts the ^ and $ at the beginning and end of the expression but I have left them there for clarity of what the expression does (for those who really know what regular expressions mean Winking)

Disabled Edit and Details links

Figure 1 - Disabled Edit and Details links

In Figure 1 we see the Edit and Details links are disabled, but the Delete is still enabled this is because there is no route for Delete and so it is not controlled by routing.

!Important: In Visual Studio 2010 and .Net 4 the links still appear to be there i.e. they are not disabled but there is no URL assigned so the links do not work. so there will be a little more work to make the links disabled.

Happy coding Happy Wizzard

No comments: