Start Here
POP Forums attempts to not get in the way of your application, by working as an MVC area. All of the front-end dependencies are embedded in the Nuget packages, so there’s no need to npm packages and build and copy stuff.
How to use The Scoring Game in your own application.
Upgrading?
This version has data changes. From v21.x, run the PopForums21to22.sql script included in the PopForums.Sql project. If you need to upgrade from v16.x to v20.x, first run the PopForums16to20.sql script against your database, which is found in the PopForums.Sql project. It’s safe to run this script more than once. IMPORTANT: Going from v18 forward, because of the changes to private messages, you must first also delete all of the existing history by running DELETE FROM pf_PrivateMessage against your database. The reason that this isn’t included in the upgrade script is because you should know it’s necessary and do it on your own.
Updating your app from the legacy ASP.NET MVC world to ASP.NET Core is non-trivial, and well beyond the scope of this documentation.
Prerequisites
You’ll need the following locally:
- Visual Studio 2026 or later, with the Azure workload (community version is fine), Visual Studio for Mac or Jetbrains Rider
- Node.js (comes with npm)
- SQL Server Developer, or SQL Server running in a Docker container
- A mail sending service that supports SMTP
- Docker, to run the Azurite, Redis or ElasticSearch containers as needed (instructions below). The default
Program.csuses Redis, but a single local node can skip it (see Build).
Build vs. reference
You should definitely get to know the installation information below to understand the project structure, but understand that you can also use POP Forums by way of Nuget package references. The POPWorldMedia/POPForums.Sample project shows how you can do this without having to build this project, and it’s literally adding a Nuget package reference and adding some config stuff in Program.cs.
Reference
- Again, POPWorldMedia/POPForums.Sample is a good starting point when using POP Forums via reference, but the
PopForums.Webproject in the source code works similarly, with project references instead of NuGet references. - Reference
PopForums.MvcandPopForums.Sqlfrom Nuget. If you want to use the scale-out kits (PopForums.AzureKitandPopForums.ElasticKit), add those as well. - Starting with v19,
PopForums.Mvcincludes all of the front-end goodies, the Javascript and CSS, right in the package. - You’ll need a layout view for the forum to live in.
- Set up the various options in
Program.csas described in its comments and this documentation. appsettings.jsonwill have your forum configuration.- v23 introduced the
PopForums.AzureKit.Functionspackage, encapsulating the Azure Functions bits. These need to be hosted in a functions host, much like the one included here. - POP Forums uses ASP.NET Data Protection in multi-node or external login scenarios. Actually, the basic anti-forgery code baked into the framework does as well, so when you deploy, or swap deployment slots in Azure, you need to persist the underlying key somewhere. This is also true if you run multiple nodes (scale out). You can persist the underlying keys in a number of different ways (I prefer Azure Blob Storage). In your
Program.cs, useservices.AddDataProtection()and the appropriate extension method. If you don’t do this for multi-node, things like social logins and anti-forgery will fail and fill your error logs with stuff about broken things. If you use slots in Azure App Services, you’ll also want the Data Protection setup, otherwise the swap will cause everyone to be logged out.
For the bleeding edge, latest build from main, the CI build packages can be obtained by a MyGet feed:
- https://www.myget.org/F/popforums/api/v3/index.json (Nuget package includes the server application and front-end assets)
Build
- Clone the latest source code from GitHub, or use the production packages as described above. Build it. Before your first build, run
npm installandnpm run buildin thePopForums.Mvcproject to fetch and minify the front-end assets — this needs to happen once beforedotnet buildon a clean checkout; after that,dotnet buildkeeps them in sync automatically. - The project files require an up-to-date version of Visual Studio 2026 or later, but it also works great with Jetbrains’ Rider on Mac or Windows. I prefer it.
- This project is built on ASP.NET v10. Make sure you have the required SDK installed (v10.0.100).
- The
PopForums.Webproject is the template to use to include the forum in your app. It referencesPopForums.Mvc, which contains all of the web app-specific code, including script and CSS.PopForums.Sqlconcerns itself only with data, whilePopForumsworks entirely with business logic and defines interfaces used in the upstream projects.PopForums.AzureKitcontains a number of items to facilitate using various Azure services.PopForums.ElasticKitcontains an ElasticSearch implementation.PopForums.AzureKit.Functionsis an implementation of functions, used if you’re not using in-app context background services (see below). - The default
Program.csruns background work in Azure Functions and caches data in Redis, so run the Azurite and Redis containers described below. For a single node without them, switch to in-process background jobs and remove the Redis cache. Redis is on by default because the project’s CI build runs on two nodes, and the in-memory cache can’t keep separate nodes in sync. Locally, a single node doesn’t need it. Instead of changingProgram.cs, you can setPopForums:Cache:ForceLocalOnlytotruein yourappsettings.development.json. See Service component registration for what each option does.
Running the background services in the web context can cause some wild variations in CPU and RAM usage on a busy forum, especially in the code associated with updating the search index. If you are running in Azure, using Functions is a much better choice for consistent and predictable app performance.
Installation
- Once you’ve completed one of the above scenarios, reference or build, it’s time to fire it up, starting with the configuration file.
appsettings.json, in the root of the web project, holds the POP Forums settings. With the defaultProgram.cs, these are the ones you need:
{
"PopForums": {
"Database": {
"ConnectionString": "server=localhost;Database=popforums21;Trusted_Connection=True;TrustServerCertificate=True;"
},
"Cache": {
"ConnectionString": "127.0.0.1:6379,abortConnect=false"
},
"Queue": {
"ConnectionString": "UseDevelopmentStorage=true"
},
"Storage": {
"ConnectionString": "UseDevelopmentStorage=true"
},
"BaseImageBlobUrl": "http://127.0.0.1:10000/devstoreaccount1"
}
}
- The values in
PopForums.Webalready point at the local Docker containers, so locally you may only need to change the database connection string. When you deploy the functions host, setWebAppUrlAndAreato your forum’s URL. See Configuration for every setting, and for how to set them as environment variables in Azure. - Attempt to run the app locally via Kestrel, and go to the URL
/Forumsto see an error page about not finding the settings table. It will fail either because the database isn’t set up, or because it can’t connect to it. The biggest reason for failure is an incorrect connection string. If you change nothing locally, by default it’s looking for a local database on the default SQL Server instance calledpopforums21. - If you want to use the setup page (and you should), don’t run the SQL script. Once the POP Forums tables exist in the database, the setup page will tell you that you’re prohibited from going there.
- Point the browser to
/Forums/Setupnow, and if your connection string is correct, you should see a page with some of the basic fields to set up.If you’re running in OAuth-Only Mode, there is no setup for the fields below. The forum will attempt to set up the database, and that’s it. That mode has no email functionality, and user creation and roles are delegated to the external identity provider. See OAuth-Only Mode for more information.
- The
PopForums.Mvcpackage includes Bootstrap, which is used as the base style for the entire app. To give it your own look, you can add your own CSS to override Bootstrap in your_Layout.cshtml, or do your own build of Bootstrap with whatever variables you like. If you prefer your own build, make sure both the Javascript and CSS tags appear before theRenderSectionin your header, and set theRenderBootstrapsetting inappsettings.jsontofalse. Learn more in customization. - If you’re using Azure functions in the background, instead of embedding the background work in the web app (see Using AzureKit), you’ll want to run multiple startup projects, specifically
PopForums.WebandPopForums.FunctionsHost.
Here’s what each field on the setup page does:
| Field | What it does |
|---|---|
| Forum title | What your forum is called at the root, in an h1 tag. You can edit this (and everything else) later. |
| SMTP Server | The host name of the server you’ll connect to for sending e-mail. Enabling this functionality on your server is beyond the scope of this document, but we usually use SendGrid to send email. |
| Port | Typically 25, though some services (like Gmail) use others. |
| From e-mail address | When a user receives e-mail from the forum, it will be “from” this address. |
| Use SSL | Check if your server uses or requires SSL. |
| Use ESMTP for credentials | Check this box if you have to authenticate with your server (this is almost always the case). Checking it makes the two fields below it editable. |
| SMTP User | The user name (often the e-mail address) to authenticate with. Not editable unless “Use ESMTP” is checked. |
| SMTP Password | The password to authenticate with. Not editable unless “Use ESMTP” is checked. |
| Display name | How you want your name to appear in the forum. |
| The e-mail address you’ll use to log in. | |
| Password | The password you’ll use to log in. |
You’re almost there!
- If you typed everything you need correctly, you should see a happy result, otherwise you’ll see a stack trace and exception.
- Restart the app.
- From here, you can follow the link to the admin home page and add categories and forums. You’ll be logged in as the user you created, and that account will be part of the Admin and Moderator roles.
- Once you’ve added some forums on the “Forums” admin page, you can go to
/Forumsto start posting. - If you want to test your e-mail setup, go to
/Forums/Account/Forgotand enter your e-mail address. Failures are also logged in the error log, which is found in the admin area. - For future reference, you can revisit the admin area at
/Forums/Admin, and when you’re logged in as an admin, a link appears in the user dropdown from the navigation menu.
Integration
The PopForums.Web project is the template you can use as the basis for your own POP Forums apps. If you want to build via the most recent stable builds, the POPWorldMedia/POPForums.Sample project is an example of how to do that (see above). The app uses the standard claims-based authentication, but it does not use Identity or Entity Framework. When you’re logged in, you’ll find the identity of the user on the User property of the controller as expected. The PopForumsAuthorizationMiddleware loads user and profile data into the request pipeline, so it can be loaded once and used throughout the request lifecycle.
Accessing the user data can be achieved via an instance of IUserRetrievalShim, which you can inject into your dependency chain. From a controller, simply call _userRetrievalShim.GetUser() to get the fully hydrated POP Forums User, or _userRetrievalShim.GetProfile() to get the profile. Under the hood, these are stored in the Items collection of the current HttpContext.
The easiest way to integrate with an existing set of users is to connect via an OAuth2 provider. Read more about OAuth-Only Mode.
Running third-party services in Docker containers
If you want to run locally with some of the “kits” described in the documentation, you’ll need to fire them up using Docker. Here are the commands for the most common things. These sometimes change because of new names, versions and such.
- SQL Server (keep in mind that
mcr.microsoft.com/azure-sql-edgeis the ARM version of SQL)
docker run --cap-add SYS_PTRACE -e 'ACCEPT_EULA=1' -e 'MSSQL_SA_PASSWORD=P@ssw0rd' -p 1433:1433 --name sqledge -d mcr.microsoft.com/azure-sql-edge - Azurite, for storage and queues
docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azurite - Redis, for distributed cache and SignalR backplane
docker run --name some-redis -p 6379:6379 -d redis - ElasticSearch, for better search
docker run --name es-9 -p 9200:9200 -e discovery.type=single-node -it docker.elastic.co/elasticsearch/elasticsearch:9.3.0
You may want to have your databases be more durable in the event you trash the SQL container or update to a new one. To do that, first create a new volume, either in Docker Desktop or on the command line:
docker volume create sqldata
Then fire up the container and associate it with the volume, and tell it to use that volume for all of the data.
docker run -e 'ACCEPT_EULA=1' -e 'MSSQL_SA_PASSWORD=P@ssw0rd' -p 1433:1433 --name sqledge -v sqldata:/DATA -d mcr.microsoft.com/azure-sql-edge
If you would like to host the data files in your own file system, you can start the container like this, replacing the approprirate paths to your local spots, where <host directory> is your spot:
docker run -e 'ACCEPT_EULA=1' -e 'MSSQL_SA_PASSWORD=P@ssw0rd' -p 1433:1433 --name sql2022 -v <host directory>:/var/opt/mssql/data -d mcr.microsoft.com/mssql/server:2022-latest
And if you need to copy files out of an existing container, you can do that too. ~/sqlvolumes in this case points to a folder in my user folders on a Mac:
docker cp containerID3bed54c7734b:/var/opt/mssql ~/sqlvolumes
Running Azure Functions on a Mac
This isn’t the most straightfoward thing, and it’s hard to find the information, but you need to install the Azure Functions Core tools via Homebrew. Microsoft explains how to do this. JetBrains’ Rider has an Azurite runner built-in to its tooling.
Customization
To make POP Forums look the way you want, or with extra functionality, read up on customization.