Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protobuf map unserialization issue

Consider the following .proto definition:

syntax = "proto3";
option csharp_namespace = "Test";

message Book
{
    string name = 1;
    map<string, PersonInfo> persons = 2;
}

message PersonInfo
{
    string name = 1;
    string details = 2;
}

I want to serialize to a file an instance of Book and later deserialize it:

 var book1 = new Book() { Name = "Book1" };
 book1.Persons.Add("Person1", new PersonInfo() { Name = "Person1", Details = "Some details" });

 //serialization
 var book1JsonStr = JsonSerializer.Serialize(book1);

 //unserialization
 var book2 = JsonSerializer.Deserialize<Book>(book1JsonStr);

The object book1 is populated correctly:

enter image description here

And the serialized string is also correct:

enter image description here

The issue arises when we unserialize the object back:

enter image description here

"Regular" fields (string, double, int) are unserialized, but the map (Google.Protobuf.Collections.MapField<TKey, TValue>) it is not. Why this is happening? Is this a bug?

What can I do to unserialize a MapField?

like image 227
Sturm Avatar asked Jul 31 '26 00:07

Sturm


2 Answers

Using Newtonsoft.Json instead of System.Text.Json solved this issue.

 var book1 = new Book() { Name = "Book1" };
 book1.Persons.Add("Person1", new PersonInfo() { Name = "Person1", Details = "Some details" });

 //serialization
 var book1JsonStr = JsonConvert.SerializeObject(book1);

 //unserialization
 var book2 = JsonConvert.SerializeObject<Book>(book1JsonStr);
like image 183
Sturm Avatar answered Aug 01 '26 12:08

Sturm


You can use Protobuf.System.Text.Json extension for System.Text.Json to fix your issue (which can be found as a NuGet package).

var book1 = new Book() { Name = "Book1" };
book1.Persons.Add("Person1", new PersonInfo() { Name = "Person1", Details = "Some details" });

//serialization
var jsonSerializerOptions = new JsonSerializerOptions();
jsonSerializerOptions.AddProtobufSupport();
var book1JsonStr = JsonSerializer.Serialize(book1, jsonSerializerOptions);

//deserialization
var book2 = JsonSerializer.Deserialize<Book>(book1JsonStr, jsonSerializerOptions);
like image 44
Hav Avatar answered Aug 01 '26 14:08

Hav



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!