Share via

Can I get the content of a Dictionary using the NrbfDecoder?

Jeroen van den Berg 20 Reputation points
2024-11-29T17:02:26.5333333+00:00

Hi,

I'm following the guide to migrate away from BinaryFormatter. Part of my requirements is that a new version of the application that no longer uses BinaryFormatter will still be able to read payloads generated by the BinaryFormatter. I am trying to use the NrbfDecoder for this, see https://learn.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-migration-guide/read-nrbf-payloads. It seems to work well with primitive types and classes. But I haven't been able to find a way to read the content of a Dictionary with it. Is this possible? Thanks!

Developer technologies | .NET | Other
{count} votes

Answer accepted by question author
  1. Anonymous
    2024-12-06T02:59:25.64+00:00

    Hi @jeroen van den berg , Welcome to Microsoft Q&A,

    // Decode NRBF data
    using var stream = new MemoryStream(payload);
    var rootRecord = NrbfDecoder.DecodeClassRecord(stream);
    
    // Locate dictionary record
    ClassRecord dictionaryRecord = rootRecord.GetClassRecord("MyDictionary");
    
    // Extract key array
    SZArrayRecord<string> keyArrayRecord = (SZArrayRecord<string>)dictionaryRecord.GetArrayRecord("Keys");
    string[] keys = keyArrayRecord.GetArray();
    
    // Extract value array
    SZArrayRecord<int> valueArrayRecord = (SZArrayRecord<int>)dictionaryRecord.GetArrayRecord("Values");
    int[] values ​​= valueArrayRecord.GetArray();
    
    // Rebuild dictionary
    var dictionary = new Dictionary<string, int>();
    for (int i = 0; i < keys.Length; i++) { dictionary[keys[i]] = values[i]; } // Output dictionary content foreach (var kvp in dictionary) { Console.WriteLine($"{kvp.Key}: {kvp.Value}"); }
    

    updated:

    The solution is working with a Dictionary<int, int> rather than a Dictionary<string, int>):

       ArrayRecord keyValuePairsRecord = dictionaryRecord.GetArrayRecord("KeyValuePairs");
    
                Array array = keyValuePairsRecord.GetArray(typeof(KeyValuePair<int, int>[]));
    
                foreach (ClassRecord keyValuePairRecord in array.Cast<ClassRecord>())
                {
                    int key = keyValuePairRecord.GetInt32("key");
                    int value = keyValuePairRecord.GetInt32("value");
    
                    Console.WriteLine(keyValuePairRecord);
                }
    

    Best Regards,

    Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. karlsarch 0 Reputation points
    2025-09-07T01:13:47.1166667+00:00

    I found the above solutions to not work when attempting to decode and deserialize a ListDictionary. After digging into the decoded structure, this worked for me. My ListDictionary has string for the key, and the values are either bool, int, or string, depending on the key. The serialized dictionary treated the values as object.

    // 'fs' is the binaryFormatter stream being processed.            
    var legacyRecord = NrbfDecoder.DecodeClassRecord(fs);
    
    		if (legacyRecord.TypeNameMatches(typeof(System.Collections.Specialized.ListDictionary)))
                {
                    var itemCount = legacyRecord.GetInt32("count");
                    var kvRecord = legacyRecord.GetClassRecord("head");
                    int i = 0;
                    while(i < itemCount)
                    {
                        var key = kvRecord.GetString("key");
                        Console.WriteLine($"Key: {key}");
                        switch (key)
                        {
                            case "IsBackupPerformed":
                            case "IsBackupPrompted":
                            case "Activated":
                                var boolVal = kvRecord.GetBoolean("value");
                                Console.WriteLine($"Boolean value: {boolVal}");
                                break;
                            case "BackupFolder":
                            case "LastSavedFilepath":
                                var strVal = kvRecord.GetString("value");
                                Console.WriteLine($"String value: {strVal}");
                                break;
                            case "BackupInterval":
                            case "RunCount":
                                var intVal = kvRecord.GetInt32("value");
                                Console.WriteLine($"Integer value: {intVal}");
                                break;
                            default:
                                Console.WriteLine($"Unrecognized Key");
                                break;
                        }
                        kvRecord = kvRecord.GetClassRecord("next");
                    }
    
    
    0 comments No comments

  2. Real Estate Jot 0 Reputation points
    2024-12-06T06:18:24.2566667+00:00

    Yes, you can extract the content of a dictionary using the NrbfDecoder. The NrbfDecoder is a part of the .NET framework that helps decode data in NRBF (Natural Binary Format) used in .NET serialization. If you have a dictionary serialized in NRBF format, you can use the NrbfDecoder to deserialize it into a dictionary object, allowing you to retrieve and manipulate its content. Ensure you handle the decoding process properly to avoid errors, especially with complex data structures. This is a powerful tool for working with binary serialized data in .NET applications.

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.