Skip to main content

Files, Reports, and Browser Boundaries

The import that read C:\Orders\in.csv becomes Upload → configured storage root → importer → the reused business logic, Export to Excel becomes a managed .xlsx + Application.Download, Print Invoice becomes a server PDF in a PdfViewer, and long reports go through a process-wide report queue (progress, cancel, view, download) that every browser session sees.

Run it​

cd "LearnWisej-Samples/From WinForms to the Web Course/Module 6/OrderDesk.Web"
dotnet run -f net10.0 --urls http://localhost:5606

Then open http://localhost:5606. (Visual Studio: open OrderDesk.slnx, F5.) No Office, no printer needed.

There is no login in this module: the first session of the process acts as kelly, every later one as sam (Application.Session.User), so the queue's Owner column can show two users.

What to try​

ActionWhat you should see
Upload order-batch.csv… → pick OrderDesk.Web/wwwroot/samples/order-batch.csvorder-batch.csv → 5 order(s) saved, 0 skipped, a toast, and orders 1043–1047 at the top of the invoice list (Tailspin Toys 5,652.50 after its 5 % discount). The file is stored under App_Data/uploads/
Upload a non-.csv or a file over 1 MBa warning toast; nothing is imported
Pick an order → Print Invoice (PDF)the invoice PDF, built on the server, opens in a modal PdfViewer with a Download button
Export .xlsx ⬇the browser saves Orders.xlsx (sheet "Orders"), written without Office under App_Data/exports/
Queue Q2 summarya job appears (Running, then Done after ~3 s); View result ▸ opens it, Download result ⬇ saves it
Queue invoice batch ×1,204, then Queue monthly statementthe batch runs (~36 s, progress climbing) while the statement waits; the page stays responsive. Cancel selected stops the batch and the statement starts
Open second session ↗ → queue a job therethe new tab (owner sam) sees the same queue; the job appears in both tabs within a second

Where things live​

Module 6/
└─ OrderDesk.Web/ the Wisej.NET 4 app (net10.0-windows;net10.0), port 5606
├─ Program.cs / Startup.cs session entry point (Application.MainPage) / Kestrel host (app.UseWisej())
├─ Default.html / Default.json / Web.config ← appSettings OrderDesk.StorageRoot = "App_Data"
├─ Domain/ the reused business logic (OrderService.Save computes the imported totals)
├─ Files/StorageRoot.cs the configured root: Path.Combine(Application.StartupPath, …), uploads/ exports/ reports/, SafeFileName
├─ Files/OrdersCsvImporter.cs Stream → orders (two layouts) → CustomerService.FindByName + OrderService.Save
├─ Reporting/ReportService.cs CreateOrdersWorkbook(rows) → path · CreateInvoicePdf(order) → bytes
├─ Reporting/XlsxWriter.cs dependency-free .xlsx (ZipArchive + five OpenXML parts)
├─ Reporting/InvoicePdfWriter.cs dependency-free PDF (+ WritePages for batches)
├─ Reporting/ReportQueue.cs process-wide queue: one lock, one Task.Run worker, progress, cancel
├─ Reporting/ReportBuilders.cs the three jobs (invoice batch, monthly statement, Q2 summary)
├─ Views/InvoicePreviewForm.cs PdfViewer + Download in a modal Form (caller disposes)
├─ Views/Ui.cs colours + toast helper
├─ wwwroot/samples/order-batch.csv the sample import file (8 rows → 5 orders)
├─ MainPage.cs / .Designer.cs import, invoice, export and the report queue
├─ App_Data/ created at run time: uploads/, exports/Orders-<stamp>.xlsx, reports/<id>-<name>.pdf
└─ docs/ the lab deliverables + migration-log.md

Runtime facts​

  • Upload: Wisej.Web.Upload is a button that opens the browser's picker; AllowedFileTypes = ".csv" and MaxFileSize = 1048576 filter on the client (Error fires with FileTooLarge), the server validates again. Uploaded delivers e.Files[i] with FileName, ContentLength, ContentType, InputStream.
  • PdfViewer: PdfStream = new MemoryStream(bytes) inside a Form shown with ShowDialog((form, result) => form.Dispose()).
  • Download: Application.Download(path, name) streams a file from the server disk; Application.Download(stream, name) streams bytes in memory.
  • The queue worker never touches controls. It runs in Task.Run, outside any Wisej session; pages poll it with a Wisej.Web.Timer and redraw only when ReportQueue.Signature() changes.
  • Paths: Path.Combine(Application.StartupPath, "App_Data", …) everywhere; Web.config OrderDesk.StorageRoot may be relative or absolute.
  • The projects multi-target net10.0-windows;net10.0, so dotnet run needs -f net10.0 (or -f net10.0-windows). Delete App_Data/ to reset uploads, exports and report results.