Skip to content

FileSystem/Temp GetAllKeysAsync silently omits enum, TimeSpan and DateTimeOffset keys, although they are stored and retrievable #56

Description

@matt-edmondson

What's wrong

PersistenceProviderUtilities.TryConvertToKey (Essentials/PersistenceProviderUtilities.cs ~L180) special-cases string, Guid and int, and otherwise uses Convert.ChangeType. That only works for IConvertible targets, so enum, TimeSpan, DateTimeOffset, Uri and similar types throw InvalidCastException. The broad catch turns that into false, and the key is silently dropped from GetAllKeysAsync.

Repro

var p = new FileSystemPersistenceProvider<Color>(new NativeFileSystemProvider(), new JsonSerializationProvider(), dir);
await p.StoreAsync(Color.Red, new Settings());

Observed:

enum key:           Exists(Red)=True  keys=[]  files=[Red.json]
TimeSpan key:       keys=[]
DateTimeOffset key: keys=[]

Expected: [Red], [00:05:00] and the stored DateTimeOffset. InMemoryPersistenceProvider returns them.

Why it matters

Anything that enumerates keys to list, migrate, export or selectively clear never sees these entries, with no error. Enum keys in particular are a natural choice for a fixed set of persisted slots.

Suggested fix

  • For enums, use Enum.TryParse(typeof(TKey), value, ignoreCase: false, out object? result).
  • More generally, use TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(value), which covers TimeSpan, DateTimeOffset, Uri, etc.

Ideally, fix this together with #46 (culture-dependent key formatting), so keys are formatted and parsed through one invariant helper.

Activity

  1. matt-edmondson commented on Sep 28, 2026

    @matt-edmondson
    ContributorAuthor

    Triage

    Next step: Parse keys with TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString, special-casing enums with Enum.TryParse. Add key round-trip tests to the shared provider contract tests.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingreadyFully specified; implement as written

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions