Back to Devexpress

Manage Multi-Tenancy

dashboard-402924-web-dashboard-integrate-dashboard-component-dashboard-backend-manage-multi-tenancy.md

latest35.6 KB
Original Source

Manage Multi-Tenancy

  • Feb 23, 2024
  • 14 minutes to read

The Web Dashboard control shares data sources, dashboards, and connection strings between all users. If you want to configure different access rights for different users, you can create custom storages or custom providers to implement your logic and limit access.

DashboardsCustom dashboard storage allows you to specify which dashboards the user can access, edit, and save.Data sourcesCustom data source storage allows you to specify which data sources are available to the user.Data source schemaA custom data source schema provider allows you to filter the data source for different users to show only a part of the data source.Connection stringsA custom connection string provider allows you to specify connection strings depending on the user’s access rights.Working modeThe Web Dashboard control can operate in ViewerOnly mode for unauthorized users.

When a user logs in, you can get information about this user in the current session. You can specify what permissions the current user has and what information to show the user based on their role.

Register Custom Storage and Provider Objects

To register custom storage and provider classes, call the following DashboardConfigurator methods in the application startup code:

ASP.NET Core

csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDevExpressControls();
builder.Services.AddScoped<DashboardConfigurator>((IServiceProvider serviceProvider) => {
    DashboardConfigurator configurator = new DashboardConfigurator();
    configurator.SetDashboardStorage(new CustomDashboardStorage(FileProvider.GetFileInfo("App_Data/Dashboards/").PhysicalPath));
    configurator.SetDataSourceStorage(new CustomDataSourceStorage());
    configurator.SetDBSchemaProvider(new CustomDBSchemaProvider());
    configurator.SetConnectionStringsProvider(new CustomConnectionStringProvider());

    return configurator;
});

var app = builder.Build();

ASP.NET MVC

csharp
public static void RegisterService(RouteCollection routes) {
    // ...
    DashboardConfigurator.Default.SetDashboardStorage(new CustomDashboardStorage("~/App_Data/Dashboards/"));
    DashboardConfigurator.Default.SetDataSourceStorage(new CustomDataSourceStorage());
    DashboardConfigurator.Default.SetDBSchemaProvider(new CustomDBSchemaProvider());
    DashboardConfigurator.Default.SetConnectionStringsProvider(new CustomConnectionStringProvider());
}
vb
Public Shared Sub RegisterService(ByVal routes As RouteCollection)
    ' ...
    DashboardConfigurator.Default.SetDashboardStorage(New CustomDashboardStorage("~/App_Data/Dashboards/"))
    DashboardConfigurator.Default.SetDataSourceStorage(New CustomDataSourceStorage())
    DashboardConfigurator.Default.SetDBSchemaProvider(New CustomDBSchemaProvider())
    DashboardConfigurator.Default.SetConnectionStringsProvider(New CustomConnectionStringProvider())
End Sub

Below you can find how to implement custom storages and providers.

Manage Dashboard Access

Dashboards are stored in dashboard storage. You can create custom dashboard storage and implement your own logic to specify which users can access, edit, and save dashboards. Implement the IEditableDashboardStorage interface that extends IDashboardStorage and allows you to add new dashboards to the custom storage. Define an implementation of the following interface methods:

GetAvailableDashboardsInfo

You can use the GetAvailableDashboardsInfo() method to return a list of dashboards. Create a new list with DashboardInfo objects and use Name and ID methods to limit this list for the current session.

The following code builds a storage list based on files from the specified folder. It also specifies that users can only access storage files that end with their username:

csharp
using DevExpress.DashboardWeb;
using System.Collections.Generic;
using System.IO;
using System.Web;

public class CustomDashboardStorage : IEditableDashboardStorage {
    private string dashboardStorageFolder;

    public CustomDashboardStorage(string dashboardStorageFolder) {
        this.dashboardStorageFolder = dashboardStorageFolder;
    }

    public IEnumerable<DashboardInfo> GetAvailableDashboardsInfo() {
        var dashboardInfos = new List<DashboardInfo>();

        var files = Directory.GetFiles(HttpContext.Current.Server.MapPath(dashboardStorageFolder), "*.xml");

        foreach (var item in files) {
            var name = Path.GetFileNameWithoutExtension(item);
            var userName = (string)HttpContext.Current.Session["CurrentUser"];

            if (userName != null && name.EndsWith(userName, System.StringComparison.InvariantCultureIgnoreCase))
                dashboardInfos.Add(new DashboardInfo() { ID = name, Name = name });
        }

        return dashboardInfos;
    }
}
vb
Imports DevExpress.DashboardWeb
Imports System.Collections.Generic
Imports System.IO
Imports System.Web

Public Class CustomDashboardStorage
    Inherits IEditableDashboardStorage

    Private dashboardStorageFolder As String

    Public Sub New(ByVal dashboardStorageFolder As String)
        Me.dashboardStorageFolder = dashboardStorageFolder
    End Sub

    Public Function GetAvailableDashboardsInfo() As IEnumerable(Of DashboardInfo)
        Dim dashboardInfos = New List(Of DashboardInfo)()
        Dim files = Directory.GetFiles(HttpContext.Current.Server.MapPath(dashboardStorageFolder), "*.xml")

        For Each item In files
            Dim name = Path.GetFileNameWithoutExtension(item)
            Dim userName = CStr(HttpContext.Current.Session("CurrentUser"))
            If userName IsNot Nothing AndAlso name.EndsWith(userName, System.StringComparison.InvariantCultureIgnoreCase) Then dashboardInfos.Add(New DashboardInfo() With {
                .ID = name,
                .Name = name
            })
        Next

        Return dashboardInfos
    End Function
End Class

LoadDashboard

Implement the LoadDashboard(String) method to load a dashboard with the specified identifier from the storage. If the dashboard is not available for the current user, you can throw an exception.

The code below parses a dashboard from an XML file depending on the current user name and throws the following exception if you do not have access to the dashboard:

You are not authorized to view this dashboard.

csharp
using DevExpress.DashboardWeb;
using System;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml.Linq;

public class CustomDashboardStorage : IEditableDashboardStorage {
    private string dashboardStorageFolder;

    public CustomDashboardStorage(string dashboardStorageFolder) {
        this.dashboardStorageFolder = dashboardStorageFolder;
    }

    public XDocument LoadDashboard(string dashboardID) {
        if (GetAvailableDashboardsInfo().Any(di => di.Name == dashboardID)) {
            var path = HttpContext.Current.Server.MapPath(dashboardStorageFolder + dashboardID + ".xml");
            var content = File.ReadAllText(path);
            return XDocument.Parse(content);
        }
        else {
            throw new ApplicationException("You are not authorized to view this dashboard.");
        }
    }
}
vb
Imports DevExpress.DashboardWeb
Imports System
Imports System.IO
Imports System.Linq
Imports System.Web
Imports System.Xml.Linq

Public Class CustomDashboardStorage
    Inherits IEditableDashboardStorage

    Private dashboardStorageFolder As String

    Public Sub New(ByVal dashboardStorageFolder As String)
        Me.dashboardStorageFolder = dashboardStorageFolder
    End Sub

    Public Function LoadDashboard(ByVal dashboardID As String) As XDocument
        If GetAvailableDashboardsInfo().Any(Function(di) di.Name = dashboardID) Then
            Dim path = HttpContext.Current.Server.MapPath(dashboardStorageFolder & dashboardID & ".xml")
            Dim content = File.ReadAllText(path)
            Return XDocument.Parse(content)
        Else
            Throw New ApplicationException("You are not authorized to view this dashboard.")
        End If
    End Function
End Class

AddDashboard

The AddDashboard(XDocument, String) method adds a new dashboard to the current IEditableDashboardStorage instance. When you implement this method, you can add a condition that specifies if users can add dashboards.

The following code allows to add new dashboards to dashboard storage only if the current user is Admin. Otherwise, the app throws the exception:

You are not authorized to add dashboards.

csharp
using DevExpress.DashboardWeb;
using System;
using System.IO;
using System.Web;
using System.Xml.Linq;

public class CustomDashboardStorage : IEditableDashboardStorage {
    private string dashboardStorageFolder;

    public CustomDashboardStorage(string dashboardStorageFolder) {
        this.dashboardStorageFolder = dashboardStorageFolder;
    }  

    public string AddDashboard(XDocument dashboard, string dashboardName) {
        var userName = (string)HttpContext.Current.Session["CurrentUser"];

        if (userName == null || userName != "Admin")
            throw new ApplicationException("You are not authorized to add dashboards.");

        var path = HttpContext.Current.Server.MapPath(dashboardStorageFolder + dashboardName + "_" + userName + ".xml");

        File.WriteAllText(path, dashboard.ToString());

        return Path.GetFileNameWithoutExtension(path);
    }
}
vb
Imports DevExpress.DashboardWeb
Imports System
Imports System.IO
Imports System.Web
Imports System.Xml.Linq

Public Class CustomDashboardStorage
    Inherits IEditableDashboardStorage

    Private dashboardStorageFolder As String

    Public Sub New(ByVal dashboardStorageFolder As String)
        Me.dashboardStorageFolder = dashboardStorageFolder
    End Sub

    Public Function AddDashboard(ByVal dashboard As XDocument, ByVal dashboardName As String) As String
        Dim userName = CStr(HttpContext.Current.Session("CurrentUser"))
        If userName Is Nothing OrElse userName <> "Admin" Then Throw New ApplicationException("You are not authorized to add dashboards.")
        Dim path = HttpContext.Current.Server.MapPath(dashboardStorageFolder & dashboardName & "_" & userName & ".xml")
        File.WriteAllText(path, dashboard.ToString())
        Return Path.GetFileNameWithoutExtension(path)
    End Function
End Class

SaveDashboard

The SaveDashboard(String, XDocument) method saves the specified dashboard to the current storage. Implement this method and specify which users can save newly created dashboards.

The following code only allows users with Admin to save modified dashboards:

csharp
using DevExpress.DashboardWeb;
using System;
using System.IO;
using System.Web;
using System.Xml.Linq;

public class CustomDashboardStorage : IEditableDashboardStorage {
    private string dashboardStorageFolder;

    public CustomDashboardStorage(string dashboardStorageFolder) {
        this.dashboardStorageFolder = dashboardStorageFolder;
    }

    public void SaveDashboard(string dashboardID, XDocument dashboard) {
        var userName = (string)HttpContext.Current.Session["CurrentUser"];

        if (userName == null || userName != "Admin")
            throw new ApplicationException("You are not authorized to save dashboards.");

        var path = HttpContext.Current.Server.MapPath(dashboardStorageFolder + dashboardID + ".xml");

        File.WriteAllText(path, dashboard.ToString());
    }
}
vb
Imports DevExpress.DashboardWeb
Imports System
Imports System.IO
Imports System.Web
Imports System.Xml.Linq

Public Class CustomDashboardStorage
    Inherits IEditableDashboardStorage

    Private dashboardStorageFolder As String

    Public Sub New(ByVal dashboardStorageFolder As String)
        Me.dashboardStorageFolder = dashboardStorageFolder
    End Sub

    Public Sub SaveDashboard(ByVal dashboardID As String, ByVal dashboard As XDocument)
        Dim userName = CStr(HttpContext.Current.Session("CurrentUser"))
        If userName Is Nothing OrElse userName <> "Admin" Then Throw New ApplicationException("You are not authorized to save dashboards.")
        Dim path = HttpContext.Current.Server.MapPath(dashboardStorageFolder & dashboardID & ".xml")
        File.WriteAllText(path, dashboard.ToString())
    End Sub
End Class

Manage Data Source Access

To make data sources available for users, add these data sources to data source storage. You can create custom data source storage and specify which users can access the predefined data sources. To do this, implement the IDataSourceStorage interface with the following methods:

Configure Data Sources

You can create a new dictionary where a key is the data source name and a value is the data source in the XDocument XML format. Configure data sources and add them to the dictionary to manage user permissions.

csharp
using System;
using System.Xml.Linq;
using System.Collections.Generic;
using DevExpress.DashboardCommon;
using DevExpress.DashboardWeb;
using DevExpress.DataAccess.Json;
using DevExpress.DataAccess.Sql;

public class CustomDataSourceStorage : IDataSourceStorage {
    private Dictionary<string, XDocument> documents = new Dictionary<string, XDocument>();

    private const string sqlDataSourceId1 = "SQL Data Source (Northwind)";
    private const string sqlDataSourceId2 = "SQL Data Source (CarsXtraScheduling)";
    private const string jsonDataSourceId = "JSON Data Source";

    public CustomDataSourceStorage() {
        DashboardSqlDataSource sqlDataSource1 = new DashboardSqlDataSource(sqlDataSourceId1, "NorthwindConnectionString");
        SelectQuery query1 = SelectQueryFluentBuilder
            .AddTable("Categories")
            .SelectAllColumnsFromTable()
            .Build("Categories");
        sqlDataSource1.Queries.Add(query1);
        SelectQuery query2 = SelectQueryFluentBuilder
            .AddTable("Products")
            .SelectAllColumnsFromTable()
            .Build("Products");
        sqlDataSource1.Queries.Add(query2);

        DashboardSqlDataSource sqlDataSource2 = new DashboardSqlDataSource(sqlDataSourceId2, "CarsXtraSchedulingConnectionString");
        SelectQuery query = SelectQueryFluentBuilder
            .AddTable("Cars")
            .SelectAllColumnsFromTable()
            .Build("Cars");
        sqlDataSource2.Queries.Add(query);

        DashboardJsonDataSource jsonDataSource = new DashboardJsonDataSource(jsonDataSourceId);
        jsonDataSource.JsonSource = new UriJsonSource(new Uri("https://raw.githubusercontent.com/DevExpress-Examples/DataSources/master/JSON/customers.json"));
        jsonDataSource.RootElement = "Customers";

        documents[sqlDataSourceId1] = new XDocument(sqlDataSource1.SaveToXml());
        documents[sqlDataSourceId2] = new XDocument(sqlDataSource2.SaveToXml());
        documents[jsonDataSourceId] = new XDocument(jsonDataSource.SaveToXml());
    }
}
vb
Imports System
Imports System.Xml.Linq
Imports System.Collections.Generic
Imports DevExpress.DashboardCommon
Imports DevExpress.DashboardWeb
Imports DevExpress.DataAccess.Json
Imports DevExpress.DataAccess.Sql

Public Class CustomDataSourceStorage
    Inherits IDataSourceStorage

    Private documents As Dictionary(Of String, XDocument) = New Dictionary(Of String, XDocument)()
    Private Const sqlDataSourceId1 As String = "SQL Data Source (Northwind)"
    Private Const sqlDataSourceId2 As String = "SQL Data Source (CarsXtraScheduling)"
    Private Const jsonDataSourceId As String = "JSON Data Source"

    Public Sub New()
        Dim sqlDataSource1 As DashboardSqlDataSource = New DashboardSqlDataSource(sqlDataSourceId1, "NorthwindConnectionString")
        Dim query1 As SelectQuery = SelectQueryFluentBuilder.AddTable("Categories").SelectAllColumnsFromTable().Build("Categories")
        sqlDataSource1.Queries.Add(query1)
        Dim query2 As SelectQuery = SelectQueryFluentBuilder.AddTable("Products").SelectAllColumnsFromTable().Build("Products")
        sqlDataSource1.Queries.Add(query2)
        Dim sqlDataSource2 As DashboardSqlDataSource = New DashboardSqlDataSource(sqlDataSourceId2, "CarsXtraSchedulingConnectionString")
        Dim query As SelectQuery = SelectQueryFluentBuilder.AddTable("Cars").SelectAllColumnsFromTable().Build("Cars")
        sqlDataSource2.Queries.Add(query)
        Dim jsonDataSource As DashboardJsonDataSource = New DashboardJsonDataSource(jsonDataSourceId)
        jsonDataSource.JsonSource = New UriJsonSource(New Uri("https://raw.githubusercontent.com/DevExpress-Examples/DataSources/master/JSON/customers.json"))
        jsonDataSource.RootElement = "Customers"
        documents(sqlDataSourceId1) = New XDocument(sqlDataSource1.SaveToXml())
        documents(sqlDataSourceId2) = New XDocument(sqlDataSource2.SaveToXml())
        documents(jsonDataSourceId) = New XDocument(jsonDataSource.SaveToXml())
    End Sub
End Class

GetDataSourcesID

The GetDataSourcesID() method gets identifiers of the data sources stored in the current IDataSourceStorage. Specify which identifiers to add to the dictionary depending on the user role.

The following code returns all data sources for Admin, sqlDataSourceId2 for User, and no data sources for other users:

csharp
using System.Collections.Generic;
using DevExpress.DashboardWeb;
using System.Web;

public class CustomDataSourceStorage : IDataSourceStorage {
    // ...

    public IEnumerable<string> GetDataSourcesID() {
        var userName = (string)HttpContext.Current.Session["CurrentUser"];

        if (userName == "Admin") {
            return documents.Keys;
        }
        else if (userName == "User") {
            return new string[] { sqlDataSourceId2 };
        }
        else {
            return new string[0];
        }
    }
}
vb
Imports System.Collections.Generic
Imports DevExpress.DashboardWeb
Imports System.Web

Public Class CustomDataSourceStorage
    Inherits IDataSourceStorage

    Public Function GetDataSourcesID() As IEnumerable(Of String)
        Dim userName = CStr(HttpContext.Current.Session("CurrentUser"))

        If userName = "Admin" Then
            Return documents.Keys
        ElseIf userName = "User" Then
            Return New String() {sqlDataSourceId2}
        Else
            Return New String(-1) {}
        End If
    End Function
End Class

GetDataSource

The GetDataSource(String) method loads the data source’s XML definition from the current IDataSourceStorage.

The following code checks whether the dictionary contains the specified key and returns the corresponding data source’s XML definition if the condition is true:

csharp
using System;
using System.Linq;
using System.Xml.Linq;
using DevExpress.DashboardWeb;

public class CustomDataSourceStorage : IDataSourceStorage {
    // ...

    public XDocument GetDataSource(string dataSourceID) {
        if (GetDataSourcesID().Contains(dataSourceID)) {
            return documents[dataSourceID];
        }
        else {
            throw new ApplicationException("You are not authorized to use this datasource.");
        }
    }
}
vb
Imports System
Imports System.Linq
Imports System.Xml.Linq
Imports DevExpress.DashboardWeb

Public Class CustomDataSourceStorage
    Inherits IDataSourceStorage

    Public Function GetDataSource(ByVal dataSourceID As String) As XDocument
        If GetDataSourcesID().Contains(dataSourceID) Then
            Return documents(dataSourceID)
        Else
            Throw New ApplicationException("You are not authorized to use this datasource.")
        End If
    End Function
End Class

Manage Database Schema

You can limit tables and views depending on the user role. Implement the DBSchemaProviderEx interface and the GetTables method to manage user permissions.

For example, the following code filters tables to show only the Cars table if the username is User:

csharp
using DevExpress.DataAccess.Sql;
using DevExpress.Xpo.DB;
using System.Linq;
using System.Web;

public class CustomDBSchemaProvider : DBSchemaProviderEx {
    public override DBTable[] GetTables(SqlDataConnection connection, params string[] tableList) {
        var result = base.GetTables(connection, tableList);

        var userName = (string)HttpContext.Current.Session["CurrentUser"];

        if (userName == "Admin") {
            return result;
        }
        else if (userName == "User") {
            return result.Where(t => t.Name == "Cars").ToArray();
        }
        else {
            return new DBTable[0];
        }
    }
}
vb
Imports DevExpress.DataAccess.Sql
Imports DevExpress.Xpo.DB
Imports System.Linq
Imports System.Web

Public Class CustomDBSchemaProvider
    Inherits DBSchemaProviderEx

    Public Overrides Function GetTables(ByVal connection As SqlDataConnection, ParamArray tableList As String()) As DBTable()
        Dim result = MyBase.GetTables(connection, tableList)
        Dim userName = CStr(HttpContext.Current.Session("CurrentUser"))

        If userName = "Admin" Then
            Return result
        ElseIf userName = "User" Then
            Return result.Where(Function(t) t.Name = "Cars").ToArray()
        Else
            Return New DBTable(-1) {}
        End If
    End Function
End Class

Manage Connection String Access

A custom connection string provider allows you to manage which data connections are available in the Data Source Wizard. This wizard allows users to select one of the predefined data connections, connect to a database, and select data. To create the custom connection string provider, implement the IDataSourceWizardConnectionStringsProvider interface with the following methods:

You can create a new dictionary where a key is the data connection name and a value is the connection string. Configure connection strings and add them to the dictionary:

csharp
public class CustomConnectionStringProvider : IDataSourceWizardConnectionStringsProvider {
    private Dictionary<string, string> connectionStrings = new Dictionary<string, string>();

    public CustomConnectionStringProvider() {
        connectionStrings.Add("NorthwindConnectionString", @"XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\nwind.mdb;");
        connectionStrings.Add("CarsXtraSchedulingConnectionString", @"XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\CarsDB.mdb;");
    }
}
vb
Public Class CustomConnectionStringProvider
    Inherits IDataSourceWizardConnectionStringsProvider

    Private connectionStrings As Dictionary(Of String, String) = New Dictionary(Of String, String)()

    Public Sub New()
        connectionStrings.Add("NorthwindConnectionString", "XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\nwind.mdb;")
        connectionStrings.Add("CarsXtraSchedulingConnectionString", "XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\CarsDB.mdb;")
    End Sub
End Class

GetConnectionDescriptions

The GetConnectionDescriptions() method returns the dictionary that lists the data connections by name. When you implement this method, create a dictionary and specify which connections are available in this dictionary for users depending on their role.

The following code provides access to the NorthwindConnectionString and CarsXtraSchedulingConnectionString connection strings for Admin and only CarsXtraSchedulingConnectionString for User. The other users do not have access to connection strings.

csharp
using DevExpress.DataAccess.Web;
using System.Collections.Generic;
using System.Web;

public class CustomConnectionStringProvider : IDataSourceWizardConnectionStringsProvider {
    // ...

    private Dictionary<string, string> connectionStrings = new Dictionary<string, string>();

    public CustomConnectionStringProvider() {
        connectionStrings.Add("NorthwindConnectionString", @"XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\nwind.mdb;");
        connectionStrings.Add("CarsXtraSchedulingConnectionString", @"XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\CarsDB.mdb;");
    }

    public Dictionary<string, string> GetConnectionDescriptions() {
        var connections = new Dictionary<string, string>();
        var userName = (string)HttpContext.Current.Session["CurrentUser"];

        if (userName == "Admin") {
            connections.Add("NorthwindConnectionString", "Northwind Connection");
            connections.Add("CarsXtraSchedulingConnectionString", "CarsXtraScheduling Connection");
        }
        else if (userName == "User") {
            connections.Add("CarsXtraSchedulingConnectionString", "CarsXtraScheduling Connection");
        }

        return connections;
    }
}
vb
Imports DevExpress.DataAccess.Web
Imports System.Collections.Generic
Imports System.Web

Public Class CustomConnectionStringProvider
    Inherits IDataSourceWizardConnectionStringsProvider

    Private connectionStrings As Dictionary(Of String, String) = New Dictionary(Of String, String)()

    Public Sub New()
        connectionStrings.Add("NorthwindConnectionString", "XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\nwind.mdb;")
        connectionStrings.Add("CarsXtraSchedulingConnectionString", "XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\CarsDB.mdb;")
    End Sub

    Public Function GetConnectionDescriptions() As Dictionary(Of String, String)
        Dim connections = New Dictionary(Of String, String)()
        Dim userName = CStr(HttpContext.Current.Session("CurrentUser"))

        If userName = "Admin" Then
            connections.Add("NorthwindConnectionString", "Northwind Connection")
            connections.Add("CarsXtraSchedulingConnectionString", "CarsXtraScheduling Connection")
        ElseIf userName = "User" Then
            connections.Add("CarsXtraSchedulingConnectionString", "CarsXtraScheduling Connection")
        End If

        Return connections
    End Function
End Class

GetDataConnectionParameters

The GetDataConnectionParameters(String) method returns the parameters of a specific data connection. Return the CustomStringConnectionParameters objects for users that have the corresponding permissions.

csharp
using DevExpress.DataAccess.ConnectionParameters;
using DevExpress.DataAccess.Web;
using System;
using System.Collections.Generic;

public class CustomConnectionStringProvider : IDataSourceWizardConnectionStringsProvider {
    // ...
    private Dictionary<string, string> connectionStrings = new Dictionary<string, string>();

    public CustomConnectionStringProvider() {
        connectionStrings.Add("NorthwindConnectionString", @"XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\nwind.mdb;");
        connectionStrings.Add("CarsXtraSchedulingConnectionString", @"XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\CarsDB.mdb;");
    }

    public DataConnectionParametersBase GetDataConnectionParameters(string name) {
        if (GetConnectionDescriptions().ContainsKey(name)) {
            return new CustomStringConnectionParameters(connectionStrings[name]);
        }
        else {
            throw new ApplicationException("You are not authorized to use this connection.");
        }
    }
}
vb
Imports DevExpress.DataAccess.ConnectionParameters
Imports DevExpress.DataAccess.Web
Imports System
Imports System.Collections.Generic

Public Class CustomConnectionStringProvider
    Inherits IDataSourceWizardConnectionStringsProvider

    Private connectionStrings As Dictionary(Of String, String) = New Dictionary(Of String, String)()

    Public Sub New()
        connectionStrings.Add("NorthwindConnectionString", "XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\nwind.mdb;")
        connectionStrings.Add("CarsXtraSchedulingConnectionString", "XpoProvider=MSAccess; Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\CarsDB.mdb;")
    End Sub

    Public Function GetDataConnectionParameters(ByVal name As String) As DataConnectionParametersBase
        If GetConnectionDescriptions().ContainsKey(name) Then
            Return New CustomStringConnectionParameters(connectionStrings(name))
        Else
            Throw New ApplicationException("You are not authorized to use this connection.")
        End If
    End Function
End Class

Prevent Unauthorized Access

For unauthorized users and guests, you can display dashboards in ViewerOnly mode to prevent inadvertent or unauthorized modifications to dashboards stored on a server. To do this, handle the DashboardConfigurator.VerifyClientTrustLevel event and set the ClientTrustLevel property to Restricted. In this case, the unauthorized users can only view the dashboards.

More information about security:

Example - How to Implement Multi-Tenant Dashboard Architecture

The examples below show how to configure the Web Dashboard so that it works in the multi-user environment. You can identify a user in the current session and return the user-specific content.

View Example: ASP.NET Core View Example: ASP.NET MVC View Example: Blazor Server

Example - How to Load Different Data Based on the Current User

The following examples configure the Dashboard control so that it loads data based on the current user. You can identify a user in the current session and handle the events to select the underlying data source.

View Example: ASP.NET CoreView Example: ASP.NET MVC

Example - How to Use Separate Server-Side Settings for Different Views

The following examples illustrate how to use separate DashboardConfigurator instances within an application to provide different server-side settings. In this example, the Sales and Marketing views use different dashboard storages.

View Example: ASP.NET CoreView Example: ASP.NET MVC