Skip to content

Generate delimited export text

This operation transforms any IEnumerable(Of T) collection into a single delimited text string (CSV by default), using reflection to discover the public properties of T at runtime. It runs synchronously, in-memory, whenever a caller (presumed to be a Legal web page or code-behind) needs to render a collection as exportable text, for example to stream back to the browser as a file download.*

Field Value
Operation ID OP-EXPORT-001
Trigger Caller invokes ExportServices.GetCSV(Of T)
Inputs inColl As IEnumerable(Of T), optional Delimiter As String = ",", optional UseQuotes As Boolean = True
Outputs String — delimited header row plus data rows, or an empty string if the input collection is empty
Primary components ExportServices.GetCSV(Of T)
Entry point SAIF.Services.Export\ExportServices.vb

Steps

  1. Accept the IEnumerable(Of T) collection plus the optional Delimiter (default ,) and UseQuotes (default True) arguments.
  2. If inColl is empty: skip directly to step 6 and return an empty string.
  3. Use TypeDescriptor.GetProperties on the first item in the collection to obtain the set of public properties of T via reflection.
  4. Build the header row: for each property, append its name to a StringBuilder.
  5. If UseQuotes is True: wrap the name in double quotes, escaping any embedded quote as "".
  6. Otherwise: append the raw property name.
  7. Separate property names with Delimiter; terminate the header line with vbCrLf.
  8. For each item in the collection, re-resolve its PropertyDescriptorCollection and, for each property, read its value via CurrentProperty.GetValue(item).
  9. Append each property's value to the current data row.
  10. If the value is non-null: append its .ToString() representation — quoted (with embedded-quote escaping) when UseQuotes is True, or raw otherwise — separated by Delimiter.
  11. If the value is null: silently skip it (no placeholder/empty field is emitted).*
    • On this condition: subsequent columns in that row can become misaligned relative to the header row when a null value occurs mid-row.*
  12. Terminate each completed data row with vbCrLf.
  13. If the input collection was empty, return an empty string (no header, no rows).
  14. Return the assembled String to the caller.

No step in this operation delegates to another SAIF business/application/framework library; all logic is self-contained BCL reflection (System.ComponentModel.TypeDescriptor) and string-building (System.Text.StringBuilder).

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([Caller invokes GetCSV]) --> Check{Collection empty?}
    Check -->|Yes| EndEmpty([Return empty string])
    Check -->|No| Props[Get properties of T via TypeDescriptor]
    Props --> Header[Build header row]
    Header --> Loop[For each item: read property values]
    Loop --> Null{Value is null?}
    Null -->|Yes| Skip[Skip value - no placeholder]
    Null -->|No| Append[Append quoted/raw value]
    Skip --> More{More items?}
    Append --> More
    More -->|Yes| Loop
    More -->|No| EndOk([Return assembled string])

Failure and edge-case behavior

  • Empty input collection: returns an empty string with no header row and no data rows.
  • Null property value mid-row: silently skipped rather than emitted as an empty placeholder, which can misalign column counts across data rows.*
  • No exception handling is present in the method; reflection or ToString() failures on individual property values would propagate to the caller.**

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.

Sources

  • SAIF.Services.Export\ExportServices.vb
  • .saifdocgen\state\runs\20260821-113120-claims-bof-web-legal\analysis\TSK009-analysis.md