Project Templates

The PowerPortalsPro project template scaffolds a complete Blazor Server portal with Dataverse connectivity, authentication, security handlers, localization, and pre-built identity pages — ready to run in minutes.

Installing the Template

Install the PowerPortalsPro.AspNetCore.Templates package from NuGet using the .NET CLI:

dotnet new install PowerPortalsPro.AspNetCore.Templates

Creating a New Project

Once installed, create a new project using the CLI or from Visual Studio's "New Project" dialog by searching for "Power Portals Pro".

dotnet new powerportalspro -o MyPortal

What's Included

The template generates a fully functional portal project with the following:

Understanding Program.cs

The Program.cs file is where all services are registered and the application pipeline is configured. Here is a breakdown of each section:

Distributed Cache

The template registers a memory-based distributed cache. In production, replace this with a persistent cache like Redis or SQL Server for better performance across multiple instances.

builder.Services.AddDistributedMemoryCache();

Fluent UI Registration

AddPowerPortalsProWebBlazorFluentUI() registers all Fluent UI Blazor components used by PowerPortalsPro editors, grids, and layout components.

builder.Services.AddPowerPortalsProWebBlazorFluentUI();

Server Services

AddPowerPortalsProWebServer() registers the core server-side services including the Dataverse data access layer, security enforcement, interceptor pipeline, and localization loading.

builder.Services.AddPowerPortalsProWebServer()

Dataverse Connection

The ConnectionOptions configuration specifies how the portal authenticates with Dataverse. The template uses Client Secret authentication with credentials stored in appsettings.json or User Secrets.

.Configure<ConnectionOptions>((options) =>
{
    options.AuthenticationType = AuthenticationType.ClientSecret;
    options.ServiceUri = new Uri(builder.Configuration.GetRequiredValue("D365:Url"));
    options.ClientId = builder.Configuration.GetRequiredValue("D365:ClientId");
    options.ClientSecret = builder.Configuration.GetRequiredValue("D365:Secret");
})

Tip

For security best practices, store your credentials in User Secrets during development and Azure Key Vault or environment variables in production. Never commit secrets to source control.

Localization Configuration

AddLocalizationDirectory registers directories containing localization JSON files. AddTablesToLocalize specifies which Dataverse tables should have their labels, column names, and view names automatically localized.

.Configure<LocalizationOptions>(options =>
{
    options.AddLocalizationDirectory("localization");
    options.AddTablesToLocalize(new List<string> { });
})

Identity Options

The IdentityOptions section configures ASP.NET Core Identity settings such as requiring email confirmation before login.

.Configure<IdentityOptions>(options =>
{
    options.SignIn.RequireConfirmedAccount = true;
})

Security Handler Registration

Permission handlers are registered in the DI container to control CRUD access for each table. The template includes handlers for Account (full access) and Contact (read-only with owner-based updates).

builder.Services.AddTransient<ITablePermissionHandler, AccountTablePermissionHandler>();
builder.Services.AddTransient<ITableRecordPermissionHandler, ContactTablePermissionHandler>();
builder.Services.AddTransient<ITableRecordPermissionHandler, ExternalLoginPermissionHandler>();

Email Configuration

The EmailServiceOptions configures the sender email address used for account confirmation and password reset emails. This is sent via the Dataverse email service.

builder.Services.Configure<EmailServiceOptions>(options =>
{
    options.EmailSenderEmailAddress = builder.Configuration
        .GetRequiredValue("D365:EmailSenderEmailAddress");
});

Microsoft Authentication (Optional)

The template includes commented-out code for adding Microsoft Entra ID (Azure AD) authentication. Uncomment and configure your Client ID and Secret to enable external login via Microsoft accounts.

builder.Services.AddAuthentication().AddMicrosoftAccount(microsoftOptions =>
{
    microsoftOptions.ClientId = builder.Configuration
        .GetRequiredValue("Authentication:Microsoft:ClientId");
    microsoftOptions.ClientSecret = builder.Configuration
        .GetRequiredValue("Authentication:Microsoft:ClientSecret");
});

Middleware Pipeline

UsePowerPortalsProWebServer() adds the PowerPortalsPro middleware. UseLocalization() enables the localization system. MapAdditionalIdentityEndpoints() registers the cookie-based login endpoint used by the identity pages.

app.UsePowerPortalsProWebServer();
app.UseLocalization();
app.MapAdditionalIdentityEndpoints();

Two-Factor Authentication (Optional)

The template includes commented-out code for enabling Two-Factor Authentication using email-based codes. Uncomment the AuthenticatorTokenProvider option and the AddDefaultTokenProviders() call to enable it.

// In Configure<IdentityOptions>:
options.Tokens.AuthenticatorTokenProvider = TokenOptions.DefaultEmailProvider;

// After the main service registration:
builder.Services.AddIdentityCore<Contact>()
    .AddDefaultTokenProviders();

Common Customizations

After scaffolding the project, here are common next steps: