Project Templates
PowerPortalsPro ships two project templates that scaffold a complete portal — Dataverse connectivity, authentication, security handlers, localization, and pre-built identity pages — ready to run in minutes. A React single-page app (recommended) and a Blazor web app are both available, and the PowerPortalsPro feature set is identical across the two. Pick whichever front-end stack fits your team.
Installing the Templates
Install the PowerPortalsPro.AspNetCore.Templates package from NuGet using the .NET CLI. Both templates ship in this one package:
dotnet new install PowerPortalsPro.AspNetCore.Templates
Choosing a Template
Once installed, create a project from the .NET CLI or Visual Studio's "New Project" dialog (search for "Power Portals Pro"). Two templates are available — choose the one that matches your front-end stack:
React (Recommended)
An ASP.NET Core host paired with a React + Vite + TypeScript single-page app built on Fluent UI React. Recommended for new portals — modern front-end tooling, a fast hot-reload dev loop, and the broadest component set.
dotnet new powerportalspro-react -o MyPortal
Blazor
An ASP.NET Core Blazor web app built on Fluent UI Blazor, with a render mode you choose at scaffold time via --interactivity. A great fit when your team works primarily in C# and prefers to stay entirely in the .NET UI stack.
dotnet new powerportalspro -o MyPortal --interactivity Auto
Recommended
Both templates expose the same PowerPortalsPro capabilities — grids, editors, security, localization, and identity. We suggest React for new projects unless your team has a specific reason to stay all-C#, in which case the Blazor template is fully supported.
The React Template
The powerportalspro-react template generates two projects that run together:
- ASP.NET Core host — serves the framework's data and auth endpoints under
/api/*and hosts the built SPA. ItsProgram.csis configured much like the Blazor host (Dataverse connection, localization, security handlers) and exposes the JSON auth endpoints viaMapAuthEndpoints<PortalUser>(). - React client (
.Client) — a Vite + TypeScript SPA built on Fluent UI React, consuming the@powerportalspro/core,@powerportalspro/react,@powerportalspro/react-fluent, and@powerportalspro/react-chartspackages for the transport layer, hooks, and components. - Dev loop — press F5 (or run
dotnet run) on the host and the SpaProxy launches the Vite dev server for you, with hot-module reload on client edits. No separate terminal required. - Same surface as Blazor — sample Accounts / Contacts pages, identity and account-management pages, table permission handlers, navigation, and theme / site settings, all rebuilt with React components.
Blazor Interactivity Modes
The Blazor template additionally accepts --interactivity Server, --interactivity WebAssembly, or --interactivity Auto to pick its render mode (the React template is always a single-page app, so it has no equivalent option). Picking a mode up front only affects the generated project layout — PowerPortalsPro itself runs correctly under all three. See the Blazor Interactivity page for a full comparison.
- Server — interactive pages execute on the server over a SignalR connection. Simplest deployment and smallest client download. Good default when you're unsure.
- WebAssembly — interactive pages run in the browser as compiled .NET code. Scaffolds a separate
.Clientproject; the server hosts the API endpoints consumed by the client. Best for rich client-side UX and offloading interaction work from the server. - Auto — renders the first paint on the server for fast perceived load, then transparently hands off to WebAssembly once the client bundle is downloaded. Combines the best of both at the cost of a slightly more complex project layout.
Tip
The
--interactivityflag matches the stockdotnet new blazortemplate's flag of the same name, so anything you already know about Blazor render modes carries over.
Template Options
Both templates expose dotnet new options so you can tailor the generated project up front. Pass them on the command line, or pick them in Visual Studio's project-creation screen (and the dotnet new interactive UI). The most useful options:
--user-audience(External|Internal|Both, defaultBoth) — who signs in. External users get local accounts (register, login, password reset) plus any external providers you enable; Internal users sign in only through Microsoft / Entra; Both enables each.--include-microsoft-login— adds Sign in with Microsoft. On by default (and required for the Internal and Both audiences). Store credentials underAuthentication:Microsoft.--include-google-login— adds Sign in with Google for external users. Provision OAuth credentials and store them underAuthentication:Google.--include-facebook-login— adds Continue with Facebook for external users. Provision an app and store its credentials underAuthentication:Facebook.--include-machine-translation+--machine-translation-provider(Azure|DeepL|Google) — wires up a machine-translation provider so the Localization Admin page can translate localization files. When omitted, the translate panel stays hidden and the registration ships as commented-out guidance.--include-sample-content(default on) /--empty— include or omit the sample pages and styling that demonstrate basic usage patterns.--interactivity(Server|WebAssembly|Auto) — the Blazor render mode (see Interactivity Modes above). Not applicable to the React template.--use-program-main— generate an explicitProgram.Mainmethod instead of top-level statements.--framework(net10.0|net9.0) — the target framework.
For example, an Auto-rendered Blazor portal for both audiences, with Google sign-in and Azure machine translation:
dotnet new powerportalspro -o MyPortal --interactivity Auto --user-audience Both --include-google-login --include-machine-translation --machine-translation-provider Azure
Tip
Run
dotnet new powerportalspro -h(ordotnet new powerportalspro-react -h) to list every option and its default. In Visual Studio these appear as checkboxes and dropdowns on the project-creation screen.
What's Included
The template generates a fully functional portal project with the following:
- Sample Pages — Accounts and Contacts list pages with MainGrid, plus detail pages with RecordContext, editors, and SubGrids.
- Identity Pages — Complete ASP.NET Core Identity integration with Login, Register, Forgot Password, Reset Password, Two-Factor Authentication, Email Confirmation, and account management pages.
- Security Handlers — Pre-built permission handlers for the Account and Contact tables demonstrating table-level and record-level security patterns.
- Layout — A MainLayout with PageLayout, desktop and mobile navigation menus, site settings, and theme support.
- Localization — A JSON localization file (
app.en.json) with navigation labels and page-specific strings. - Configuration —
appsettings.jsonwith placeholders for Dataverse connection settings.
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:
React template
The walkthrough below describes the Blazor template's
Program.cs. The React template's host registers the same core services —AddPowerPortalsProWebServer(), the DataverseConnectionOptions, localization, security handlers, and email — but omits the Blazor-specificAddPowerPortalsProWebBlazorFluentUI()registration, serves the React SPA instead, and exposes the auth endpoints viaMapAuthEndpoints<PortalUser>()rather thanMapAdditionalIdentityEndpoints().
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. By default LocalizeAllAvailableTables is true, so labels, column names, and view names are pulled from every Dataverse table automatically. Set it to false and use AddTableToLocalize / AddTablesToLocalize to restrict localization to an explicit list.
.Configure<LocalizationOptions>(options =>
{
options.AddLocalizationDirectory("localization");
// By default, every Dataverse table is localized. To restrict
// localization to an explicit list, opt out and add the tables:
//options.LocalizeAllAvailableTables = false;
//options.AddTablesToLocalize(new List<string> { "transactioncurrency", "opportunity" });
})
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;
})
Machine Translation (optional)
Generate the project with --IncludeMachineTranslation to wire up machine translation for the Localization Admin page's Translate a file panel. The template adds the chosen provider's PowerPortalsPro.Web.Server.Translation.* package and its registration below; choose the provider with --MachineTranslationProvider: Azure (the default), DeepL, or Google. Supply the provider's key via configuration / user-secrets under Azure:Translation:Key, DeepL:Translation:Key, or Google:Translation:Key to match.
builder.Services.AddPowerPortalsProAzureTranslationService(options =>
{
options.TranslationKey = builder.Configuration
.GetValue<string>("Azure:Translation:Key") ?? string.Empty;
});
Tip
Without the option, the Localization Admin page still works — the pipeline overview and per-source / merged downloads are unaffected; only the translate panel stays hidden, and the registration ships as commented-out guidance so you can enable it later by hand.
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:
- Add permission handlers for any additional Dataverse tables your portal accesses.
- Every Dataverse table is localized by default. To opt out for a smaller footprint, set
LocalizeAllAvailableTablestofalseand list the tables you want viaAddTableToLocalize. - Register
ITableRecordInterceptorimplementations for business logic that runs before or after record operations. - Update the navigation menus in
NavMenu.razor,DesktopNavMenu.razor, andMobileNavMenu.razorto match your portal's pages. - Add new pages with
RecordContext, editors, and grids for your custom Dataverse tables.
