microsoft/teams.net

Public

mirrored from https://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v2.0.8

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/src/Microsoft.Teams.Apps/Schema/Entities/Entity.cs

170lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System.Text.Json;
5using System.Text.Json.Nodes;
6using System.Text.Json.Serialization;
7using Microsoft.Teams.Core.Schema;
8
9namespace Microsoft.Teams.Apps.Schema.Entities;
10
11
12/// <summary>
13/// List of Entity objects.
14/// </summary>
15[JsonConverter(typeof(EntityListJsonConverter))]
16public class EntityList : List<Entity>
17{
18 /// <summary>
19 /// Converts the Entities collection to a JsonArray.
20 /// </summary>
21 /// <returns></returns>
22 public JsonArray? ToJsonArray()
23 {
24 JsonArray jsonArray = [];
25 foreach (Entity entity in this)
26 {
27 JsonObject jsonObject = new()
28 {
29 ["type"] = entity.Type
30 };
31
32 foreach (KeyValuePair<string, object?> property in entity.Properties)
33 {
34 jsonObject[property.Key] = property.Value as JsonNode ?? JsonValue.Create(property.Value);
35 }
36 jsonArray.Add(jsonObject);
37 }
38 return jsonArray;
39 }
40
41 /// <summary>
42 /// Parses a JsonArray into an Entities collection.
43 /// </summary>
44 /// <param name="jsonArray"></param>
45 /// <param name="options"></param>
46 /// <returns></returns>
47 public static EntityList? FromJsonArray(JsonArray? jsonArray, JsonSerializerOptions? options = null)
48 {
49 if (jsonArray == null)
50 {
51 return null;
52 }
53 EntityList entities = [];
54 foreach (JsonNode? item in jsonArray)
55 {
56 if (item is JsonObject jsonObject
57 && jsonObject.TryGetPropertyValue("type", out JsonNode? typeNode)
58 && typeNode is JsonValue typeValue
59 && typeValue.GetValue<string>() is string typeString)
60 {
61 // TODO: Should be able to support unknown types (PA uses BotMessageMetadata).
62 // TODO: Investigate if there is any way for Parent to avoid
63 // Knowing the children.
64 // Maybe a registry pattern, or Converters?
65 Entity? entity = typeString switch
66 {
67 "clientInfo" => item.Deserialize<ClientInfoEntity>(options),
68 "mention" => item.Deserialize<MentionEntity>(options),
69 "message" or "https://schema.org/Message" => DeserializeMessageEntity(item, options),
70 "ProductInfo" => item.Deserialize<ProductInfoEntity>(options),
71 "streaminfo" => item.Deserialize<StreamInfoEntity>(options),
72 "quotedReply" => item.Deserialize<QuotedReplyEntity>(options),
73#pragma warning disable ExperimentalTeamsTargeted
74 "targetedMessageInfo" => item.Deserialize<TargetedMessageInfoEntity>(options),
75#pragma warning restore ExperimentalTeamsTargeted
76 _ => item.Deserialize<Entity>(options)
77 };
78 if (entity != null)
79 entities.Add(entity);
80 }
81 }
82 return entities;
83 }
84
85 /// <summary>
86 /// Deserializes a message entity by checking the @type property to determine the specific type.
87 /// </summary>
88 /// <param name="item">The JSON node to deserialize.</param>
89 /// <param name="options">The JSON serializer options.</param>
90 /// <returns>The deserialized entity, or null if deserialization fails.</returns>
91 private static OMessageEntity? DeserializeMessageEntity(JsonNode item, JsonSerializerOptions? options)
92 {
93 if (item is JsonObject jsonObject
94 && jsonObject.TryGetPropertyValue("@type", out JsonNode? oTypeNode)
95 && oTypeNode is JsonValue oTypeValue
96 && oTypeValue.GetValue<string>() is string oType)
97 {
98 return oType switch
99 {
100 "Message" => item.Deserialize<CitationEntity>(options),
101 "CreativeWork" => item.Deserialize<SensitiveUsageEntity>(options),
102 _ => item.Deserialize<OMessageEntity>(options)
103 };
104 }
105
106 return item.Deserialize<OMessageEntity>(options);
107 }
108}
109
110/// <summary>
111/// Entity base class.
112/// </summary>
113/// <remarks>
114/// Initializes a new instance of the Entity class with the specified type.
115/// </remarks>
116/// <param name="type">The type of the entity. Cannot be null.</param>
117public class Entity(string type)
118{
119 /// <summary>
120 /// Gets or sets the type identifier for the object represented by this instance.
121 /// </summary>
122 [JsonPropertyName("type")]
123 public string Type { get; set; } = type;
124
125 /// <summary>
126 /// Gets or sets the OData type identifier for the object represented by this instance.
127 /// </summary>
128 [JsonPropertyName("@type")] public string? OType { get; set; }
129
130 /// <summary>
131 /// Gets or sets the OData context for the object represented by this instance.
132 /// </summary>
133 [JsonPropertyName("@context")] public string? OContext { get; set; }
134 /// <summary>
135 /// Extended properties dictionary.
136 /// </summary>
137 [JsonExtensionData] public ExtendedPropertiesDictionary Properties { get; set; } = [];
138
139}
140
141/// <summary>
142/// JSON converter for EntityList.
143/// </summary>
144public class EntityListJsonConverter : JsonConverter<EntityList>
145{
146 /// <summary>
147 /// Reads and converts the JSON to EntityList.
148 /// </summary>
149 public override EntityList? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
150 {
151 if (reader.TokenType == JsonTokenType.Null)
152 {
153 return null;
154 }
155
156 JsonArray? jsonArray = JsonSerializer.Deserialize<JsonArray>(ref reader, options);
157 return EntityList.FromJsonArray(jsonArray, options);
158 }
159
160 /// <summary>
161 /// Writes the EntityList as JSON.
162 /// </summary>
163 public override void Write(Utf8JsonWriter writer, EntityList value, JsonSerializerOptions options)
164 {
165 ArgumentNullException.ThrowIfNull(value);
166 JsonArray? jsonArray = value.ToJsonArray();
167 JsonSerializer.Serialize(writer, jsonArray, options);
168 }
169}
170
171