---
title: Persist preferences
summary: Serializes and persists in-memory preferences through the framework preference service.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-17
library: SAIF.Presentation
reference_type: package
operation_id: OP-PRES-005
trigger: Consuming code finishes a batch of Add / Remove / Clear calls
---

# Persist preferences

This operation serializes every in-memory `Preference` record belonging to the store's current application to JSON and hands each one to `SAIF.Framework.Preferences.PreferenceData.SavePreferences`. This library issues no SQL; the write is executed entirely inside the `SAIF.BOF.Framework` package.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-PRES-005 |
| **Trigger** | Consuming code calls `Save()` after a batch of `Add` / `Remove` / `Clear` calls |
| **Inputs** | The in-memory `_Preferences` list, `m_DPI` |
| **Outputs** | Persisted preference records; the function always returns `False` |
| **Primary components** | `clsPreferences.Save` |
| **Entry point** | `SAIF.Presentation/clsPreferences.vb` |

## Steps

1. Log method entry via `clsLogTrace.MethodBegin()`. No SQL.
2. Construct `PreferenceData(m_DPI)`.
   - Delegates to `SAIF.Framework.Preferences`; the framework's own persistence logic is not visible from this repository.**
3. Iterate `_Preferences`, skipping any record whose `ApplicationName` differs from the store's current application ([BR-PRES-020](../business-rules.md#br-pres-020-save-persists-only-the-current-applications-records)).
4. For each matching record, serialize `PreferenceItems` to JSON with `JavaScriptSerializer` when the dictionary is non-empty, or pass an empty string when it is empty ([BR-PRES-021](../business-rules.md#br-pres-021-preference-items-persisted-as-json), [BR-PRES-022](../business-rules.md#br-pres-022-empty-preference-record-persisted-as-empty-string)).
5. Call `PreferenceData.SavePreferences(applicationName, pagename, m_DPI.UserID, json)` ([BR-PRES-023](../business-rules.md#br-pres-023-persistence-always-routed-through-preferencedata)).
   - The write is executed inside the framework package; the SQL and target table are not visible from this repository.**
6. On any exception, wrap and re-throw as `ApplicationException("Unable to save preferences.", ex)` ([BR-PRES-024](../business-rules.md#br-pres-024-persistence-failures-wrapped-in-applicationexception)).
7. Return `result`, which is never assigned and is therefore always `False`.
   - The trailing `clsLogTrace.MethodEnd()` call after `Return result` is unreachable — a verified defect in this library's source.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Save called]) --> S1[Log method entry]
	S1 --> S2[Construct PreferenceData]
	S2 --> S3[Iterate _Preferences]
	S3 --> D1{ApplicationName matches current application?}
	D1 -->|No| Skip[Skip record]
	D1 -->|Yes| S4[Serialize PreferenceItems to JSON, or empty string]
	S4 --> S5[PreferenceData.SavePreferences]
	S5 --> D2{Exception thrown?}
	D2 -->|Yes| Err([Wrap and re-throw ApplicationException])
	D2 -->|No| Loop{More records?}
	Loop -->|Yes| S3
	Loop -->|No| EndOk([Return False, unreachable MethodEnd])
	Skip --> Loop
```

## Failure and edge-case behavior
- Any exception raised by `PreferenceData.SavePreferences` is wrapped and re-thrown as `ApplicationException("Unable to save preferences.", ex)` ([BR-PRES-024](../business-rules.md#br-pres-024-persistence-failures-wrapped-in-applicationexception)).
- `Save()` always returns `False` even on success, because the `result` local is never assigned `True` — callers cannot use the return value to detect success; only a thrown `ApplicationException` signals failure.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **Note:** Statements marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Presentation/clsPreferences.vb`
