msgraph-sdk-dotnet icon indicating copy to clipboard operation
msgraph-sdk-dotnet copied to clipboard

Deserialize AdditionalData values.

Open ksikorsk opened this issue 5 years ago • 5 comments

Hi all,

One more item I wanted to raise. We use OpenType additional data extensively. We have cases where we attach complex types (mostly Identity, IdentitySet) in additional data. Today the Graph SDK deserialization does not go through additional data to deserialize it’s content to the strongly typed object, and we have our own ISerializer to achieve this. As these are valid work flows for all 3rd parties using our APIs, can we add logic into Microsoft.Graph.Core to support this?

Thanks, Kamil

AB#7313

ksikorsk avatar Feb 15 '19 20:02 ksikorsk

Doing a better job of handling the AdditionalData is something that is on our radar. Currently we put OData annotations, HTTP headers, HTTP status codes, OpenType extensions, schema extensions and new properties all into AdditionalData. We need to review how we can split out this data and make it easier to consume on the client side.

darrelmiller avatar Feb 17 '19 17:02 darrelmiller

Related to issue https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/501.

peombwa avatar Jun 27 '19 22:06 peombwa

Proposal for us:

IdentitySet i = AdditionalData.Get<IdentitySet>("propertykey") // returns deserialized object if it exists, otherwise returns null.

or

AdditionalData.TryGet<T>("propertykey", out propertyValue T) // Added as an extension method.

Currently, they can get the object and then use client.HttpProvider.Serializer.Deserialize<T>(object) to deserialize.

MIchaelMainer avatar Apr 29 '21 16:04 MIchaelMainer

Is there a way to parse members@delta in a group delta query similar to this:

response.AdditionalData.TryGetValue("@odata.nextLink", out object nextLink1); response.AdditionalData.TryGetValue("@odata.deltaLink", out object deltaLink1);

I tried this response.AdditionalData.TryGetValue("members@delta", out object members); but that doesn't work.

lipalath-ms avatar Aug 17 '22 23:08 lipalath-ms

In general, we no longer store HTTP headers and HTTP status codes in the AdditionalData. But only properties returned form the API that are not included in the schema.

In the Kiota SDK previews, the elements in the AdditionalData are automatically deserialized to primitive types (string,int,bool, DateTimeOffset ...).

https://github.com/microsoft/kiota-serialization-json-dotnet/blob/4ef5d2e5b57466fa46018bc1e55e46d78d0b2b0a/src/JsonParseNode.cs#L337.

Complex, object types are however catered for similarly

  • At the time of serialization, the desired type is unknown for the property as its not present in the schema (hence why it's in the AdditionalData)
  • The type could be custom to the project/implementation and may not follow serlialization conventions in the SDK as is the case when using custom extensions in https://learn.microsoft.com/en-us/graph/extensibility-overview

In this scenario, the following can be done

if (returnedObject.AdditionalData.TryGetValue("propertykey", out var propertyValue))
{
    var propertyElement = (JsonElement)propertyValue;
    // if the property is a known type described in the expected conventions
    var identitySet = new JsonParseNode(propertyElement).GetObjectValue<IdentitySet>(IdentitySet.CreateFromDiscriminatorValue);
}

or

if (returnedObject.AdditionalData.TryGetValue("propertykey", out var propertyValue))
{
    var propertyElement = (JsonElement)propertyValue;
    // or if my model is custom and not really tied to the expected conventions
    var identitySet2 = propertyElement.Deserialize<CustomExtension>();
}

Alternatively, the model may be extended/inherited with the provided implementations for IParsable to declare the property types and have them de-serialized.

andrueastman avatar Oct 04 '22 09:10 andrueastman