Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty 'Any' type field values cannot be correctly serialized/deserialized to JSON text in the C# library #19760

Open
tltsaia opened this issue Dec 20, 2024 · 1 comment
Assignees
Labels

Comments

@tltsaia
Copy link

tltsaia commented Dec 20, 2024

What version of protobuf and what language are you using?
Version: main/v29.2
Language: C#

What operating system (Linux, Windows, ...) and version?
Windows 10 22H2
What runtime / compiler are you using (e.g., python version or gcc version)
Visual Studio 2022
What did you do?
Steps to reproduce the behavior:

The "Any" type fields do not accept null values for packing; only an empty object instantiated with new Any() can be passed to represent a null value.
An empty "Any" object is represented as {"@type": "", "@value": ""}.
The current C# JsonFormatter and JsonParser both do not accept this input value, and both throw an error: Type registry has no descriptor for type name ''.

For example:

        var rep = new MsgFromProtoFile(); // IMessage instance
        rep.SomeAnyField = Any.Pack(new MyAnyField{ strField= "string", 
            anyField= new Any() // empty Any object, this will be {"@type": "", "@value": ""}
        });

        var tr = TypeRegistry.FromMessages(MyAnyField.Descriptor);
        var json_parser = new JsonParser(JsonParser.Settings.Default.WithTypeRegistry(tr));
        var formater = new JsonFormatter(new JsonFormatter.Settings(true).WithTypeRegistry(tr));

        var json_text = formater.Format(rep); // throw exception as above
        var rep0 = json_parser.Parse<MsgFromProtoFile>(json_text); // throw exception as above

What did you expect to see
formater return json text with null value, ex: {"anyField": null}
parser return empty Any object as expect, even if {"@type": "", "@value": ""}

What did you see instead?
throw an error: Type registry has no descriptor for type name ''.

Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs).

Anything else we should know about your project / environment
In the Golang library, an empty "Any" object represented as {"@type": "", "@value": ""} can be processed normally.

It is recommended to handle this in the function MergeAny() of Google.Protobuf.JsonParser

        string typeUrl = token.StringValue;
        string typeName = Any.GetTypeName(typeUrl);

        if (string.IsNullOrEmpty(typeName))
        {
            tokenizer.Next(); // @value
            tokenizer.Next(); // string
            tokenizer.Next(); // EndObject
            return;
        }

to handle this in the function WriteAny() of Google.Protobuf.JsonFormatter

  string typeName = Any.GetTypeName(typeUrl);

        if (string.IsNullOrEmpty(typeName))
        {
            WriteNull(writer);
            return;
        }
@tltsaia tltsaia added the untriaged auto added to all issues by default when created. label Dec 20, 2024
@zhangskz zhangskz added c# and removed untriaged auto added to all issues by default when created. labels Dec 20, 2024
@jskeet
Copy link
Contributor

jskeet commented Dec 20, 2024

I will look at this in January.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants