PPJ Web Operations
A PPJ Web application runs its .NET application logic on a server and presents its interface through Wisej.NET in the browser. Moving a desktop application to that model changes ownership: one process can serve many users, server files are not browser files, and a lost session can outlive the request that created a database change.
Use this guide to produce a deployment record and a repeatable operational test. Begin with the compatibility matrix; a successful local debug session is not a deployment test.
Publish a Reproducible Artifact
Publish with the toolchain supported by the generated project. For .NET Framework/IIS, verify the application's framework and application-pool configuration. For modern .NET, record the target framework, runtime identifier where applicable, and whether the deployment is framework-dependent or self-contained. Retain the artifact that was tested instead of rebuilding it differently for production.
Include PPJ and Wisej assemblies, application resources, themes, report definitions and schemas, provider/native dependencies, and the configuration files the installed runtime expects. Keep production secrets in the hosting environment's supported secret mechanism. Confirm which files are public web resources and which must remain private.
Run the published application as the actual service identity on a machine without the developer's PATH, personal database aliases, or Visual Studio installation. Exercise database access, license activation, fonts, temporary storage, reporting, and external services. Consult the Wisej deployment guide for the selected host.
Isolate Sessions
Ordinary C# static fields are shared across sessions in the process. Use the generated PPJ Web conventions and Wisej session facilities for user-specific state; do not replace a generated session-aware accessor with a static singleton. Immutable shared configuration is different from an editable order, current customer, report object, or SQL handle. See Wisej statics.
| State | Intended ownership | Isolation test |
|---|---|---|
| Current customer, form state, unsaved edits | User/session | Two independent browser sessions edit different records without changing each other's screen or defaults. |
| SQL handle and transaction | Explicit application operation/session ownership | One user's rollback does not affect another user's work. No simultaneous use of one mutable handle. |
| Shared lookup cache | Process or external cache, with an explicit key policy | Results are not mixed across tenants, identities, languages, or permission levels. |
| Report instance and temporary output | One report request, with authorized retrieval | Another user cannot retrieve the output by guessing its URL or filename. |
Use separate browser profiles or private sessions for this test. Two tabs may share a browser identity/session and are not sufficient evidence of isolation.
Authentication and Authorization
Choose the authentication integration for the actual host: IIS/ASP.NET authentication and ASP.NET Core middleware have different configuration paths. Confirm how the authenticated principal becomes available to the Wisej/PPJ session before opening the main application. An application login form by itself does not establish host authentication.
Authorize business operations on the server at the point of use, including downloads, exports, and record updates. Hiding a menu item is a presentation decision, not an authorization check. Define behavior for sign-out, expired credentials, role changes, and an already-open form whose permission is revoked.
Test a direct request to a protected output, a user without the required role, and an expired session attempting to save. Apply the host's documented scheme and middleware order; see ASP.NET Core authentication or the ASP.NET security overview for the relevant application model.
Files, Reports, and Printing
A path such as C:\Orders\invoice.pdf refers to the server when used by server-side code. Replace workflows that assume direct access to a user's disk with explicit upload/download actions. Browser printing also differs from opening a server printer queue.
For uploads, use a supported upload control and validate size and content on the server. Assign a server-controlled storage name, keep untrusted filenames as display metadata, and prevent them from selecting arbitrary filesystem paths. Put private files outside publicly served directories. See Wisej Upload and Microsoft's file-upload guidance.
For downloads and report exports, verify the requester can access the document, set an appropriate expiry, and clean up abandoned files. Do not reuse a shared report.pdf path for concurrent users. Retain a stream or file until the supported delivery mechanism has finished consuming it. Decide whether durable generated documents need audit retention; temporary rendering caches are not an archive.
Concurrency and Long Operations
Do not carry a desktop UI-thread assumption into server code. Keep mutable UI/session objects on the execution path supported by the installed Wisej version. Background work needs an explicit session/UI update mechanism and its own resource ownership; see context lifetime before moving code across threads or await boundaries.
Protect the business operation against duplicate submissions and concurrent edits. For example, an order-save operation can use a database version check or an application-defined idempotency key. A disabled button improves interaction but cannot guarantee a request was executed only once.
Test a second user updating the same record, a double submission, a client disconnect during a save, and a slow report alongside ordinary requests. Define which work may continue after the user leaves and how its outcome can be retrieved safely. Set timeouts from the operation's requirements and measure database, rendering, and request times separately.
Load Balancing and Recovery
Wisej requires a user's requests to reach the same server instance. Configure session affinity, and enable WebSocket forwarding when using that transport. Affinity routes requests; it does not replicate a live form or make in-memory state durable. See Wisej load balancing.
Treat a process restart, deployment, and node failure as explicit user scenarios. Decide how users are informed that unsaved work was lost and how committed operations are reconciled. For planned updates, stop accepting new sessions on the retiring node and use the application's agreed drain/timeout policy. Retain the previous tested artifact and compatible configuration for rollback; database schema changes need their own compatibility plan.
Measure readiness separately from process liveness. A server can be running while its database, license, or report storage is unavailable. Keep diagnostic endpoints and logs free of passwords, connection strings, and sensitive report data.
Release Exercise
Perform and record this sequence in the deployment environment:
- Start from the saved artifact and authenticate as two users with different permissions.
- Open different records, then the same record; verify isolation and the chosen conflict policy.
- Upload, download, and export with each identity; attempt cross-user access and an expired download.
- Exercise a SQL failure, a timeout, and a report cancellation. Confirm rollback/cleanup ownership and useful diagnostics.
- Restart a node during an active session and reconcile a save interrupted at the client. Verify the documented recovery behavior.
- Deploy and roll back using the written procedure. Check licenses, data access, assets, and session behavior again.
Save timestamps, artifact and dependency versions, user-visible results, and relevant correlation IDs. A release decision should refer to this evidence and the remaining accepted limitations.