public override void WriteJson(JsonWriter writer, [AllowNull] Entity entity, JsonSerializer serializer) { if (writer is null) { throw new ArgumentNullException(nameof(writer)); } if (serializer is null) { throw new ArgumentNullException(nameof(serializer)); } if (entity is null) { throw new ArgumentNullException(nameof(entity), "Entity can't be empty."); } var md = _metadata.GetEntityMetadata(entity.LogicalName); if (!entity.ContainsValue(md.PrimaryIdAttribute) && !Guid.Equals(entity.Id, Guid.Empty)) { entity[md.PrimaryIdAttribute] = entity.Id; } writer.WriteStartObject(); foreach (var(attributeName, attributeValue) in entity.Attributes) { var propName = attributeName; var propValue = attributeValue; if (propValue is EntityReference) { propName = $"{attributeName}@odata.bind"; } writer.WritePropertyName(propName); if (attributeValue is DateTime dateTime && _metadata.IsDateOnlyAttribute(entity.LogicalName, propName)) { propValue = dateTime.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); } serializer.Serialize(writer, propValue); } writer.WriteEndObject(); //serializer.Serialize(writer, entity.Attributes); }
public static string ToCrmBaseEntityString(this EntityReference entityReference, IWebApiMetadataService organizationMetadata) { if (entityReference is null) { throw new ArgumentNullException(nameof(entityReference)); } var logicalName = entityReference.LogicalName; var idAttributeName = organizationMetadata.GetEntityMetadata(logicalName)?.PrimaryIdAttribute; var sb = new StringBuilder("{"); sb.Append($"\"@odata.type\": \"Microsoft.Dynamics.CRM.{logicalName}\""); sb.Append(","); sb.Append($"\"{idAttributeName}\": \"{entityReference.Id}\""); sb.Append("}"); return(sb.ToString()); }
public override void WriteJson(JsonWriter writer, [AllowNull] Entity entity, JsonSerializer serializer) { if (writer is null) { throw new ArgumentNullException(nameof(writer)); } if (serializer is null) { throw new ArgumentNullException(nameof(serializer)); } if (entity is null) { throw new ArgumentNullException(nameof(entity), "Entity can't be empty."); } var md = _metadata.GetEntityMetadata(entity.LogicalName); if (!entity.ContainsValue(md.PrimaryIdAttribute) && !Guid.Equals(entity.Id, Guid.Empty)) { entity[md.PrimaryIdAttribute] = entity.Id; } writer.WriteStartObject(); // ODataType writer.WritePropertyName("@odata.type"); serializer.Serialize(writer, $"Microsoft.Dynamics.CRM.{entity.LogicalName}"); foreach (var(attributeName, attributeValue) in entity.Attributes) { var propName = attributeName; var propValue = attributeValue; if (propValue is EntityReference propValueRef) { var relationMd = _metadata.GetRelationshipMetadata(rel => rel.ReferencingEntity.Equals(entity.LogicalName, StringComparison.OrdinalIgnoreCase) && rel.ReferencingAttribute.Equals(attributeName, StringComparison.OrdinalIgnoreCase) && rel.ReferencedEntity.Equals(propValueRef.LogicalName)); if (!string.IsNullOrEmpty(relationMd?.ReferencingEntityNavigationPropertyName)) { propName = $"{relationMd.ReferencingEntityNavigationPropertyName}@odata.bind"; } else { propName = $"{attributeName}@odata.bind"; } } writer.WritePropertyName(propName); if (attributeValue is DateTime dateTime && _metadata.IsDateOnlyAttribute(entity.LogicalName, propName)) { propValue = dateTime.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); } serializer.Serialize(writer, propValue); } writer.WriteEndObject(); //serializer.Serialize(writer, entity.Attributes); }
public override EntityCollection ReadJson(JsonReader reader, Type objectType, [AllowNull] EntityCollection existingValue, bool hasExistingValue, JsonSerializer serializer) { if (hasExistingValue) { throw new NotImplementedException(); } var jObject = JObject.Load(reader); var collection = new EntityCollection(); if (jObject.TryGetValue("@odata.count", out var count)) { collection.Count = count.ToObject <int>(); } if (jObject.TryGetValue("@odata.nextLink", out var nextLink)) { collection.NextLink = nextLink.ToObject <Uri>(); } if (jObject.TryGetValue("@Microsoft.Dynamics.CRM.fetchxmlpagingcookie", out var pagingcookie)) { var xmlPagingCookie = System.Net.WebUtility.UrlDecode(pagingcookie.ToString()); var xmlDoc = System.Xml.Linq.XDocument.Parse(xmlPagingCookie); if (xmlDoc.Document?.Root?.Attribute("pagingcookie") != null) { collection.PagingCookie = System.Net.WebUtility.UrlDecode(xmlDoc.Document.Root.Attribute("pagingcookie")?.Value); } } if (jObject.TryGetValue("@odata.context", out var context) && ODataResponseReader.TryParseCollectionName(context.ToString(), out var collectionName)) { var entityMd = _metadata.GetEntityMetadata(x => x.EntitySetName == collectionName); collection.EntityName = entityMd.LogicalName; } var valueArr = jObject["value"]; if (valueArr == null) { return(collection); } foreach (var item in valueArr) { if (item is JObject jObjectEntity) { if (context != null) { jObjectEntity.Add("@odata.context", context); } var entity = jObjectEntity.ToObject <Entity>(serializer); collection.Entities.Add(entity); } } return(collection); }
public static Entity ReadEntity(IDictionary <string, object> attributes, IWebApiMetadataService metadata, JsonSerializer jsonSerializer) { var toRemove = new List <string>(); var entity = new Entity(); // Получим Etag if (attributes.TryGetValue("@odata.etag", out var etagRaw)) { entity.RowVersion = etagRaw.ToString(); toRemove.Add("@odata.etag"); } // Получим Контект if (attributes.TryGetValue("@odata.context", out var odataContext)) { if (TryParseCollectionName(odataContext.ToString(), out var entitySetName)) { //entity.EntitySetName = entitySetName; var md = metadata .GetEntityMetadata(x => string.Equals(x.EntitySetName, entitySetName, StringComparison.OrdinalIgnoreCase)); if (md != null) { entity.LogicalName = md.LogicalName; toRemove.Add("@odata.context"); if (attributes.ContainsKey(md.PrimaryIdAttribute)) { entity.Id = new Guid(attributes[md.PrimaryIdAttribute].ToString()); } } } } // Отберём все lookuplogicalname var entityReferenceAttributes = attributes .Where(a => a.Key.EndsWith("@Microsoft.Dynamics.CRM.lookuplogicalname", StringComparison.OrdinalIgnoreCase)) .ToArray(); // Обходим коллекцию Ссылочных аттрибутов foreach (var(attribute, value) in entityReferenceAttributes) { var key = attribute.Split('@')[0]; //_organizationid_value //_organizationid_value, //[email protected], //[email protected] //[email protected] var complements = attributes .Where(a => a.Key.StartsWith(key, StringComparison.Ordinal)).ToArray(); var logicalName = value.ToString(); var id = Guid.Parse(complements.First(a => a.Key == key).Value.ToString()); var entityReference = new EntityReference(logicalName, id) { Name = complements.FirstOrDefault(c => IsFormatedValue(c.Key)).Value?.ToString(), LogicalName = complements .FirstOrDefault(c => c.Key.EndsWith("@Microsoft.Dynamics.CRM.lookuplogicalname", StringComparison.Ordinal)) .Value?.ToString() }; var navPropertyName = FormatAttributeName(key); entity.Attributes.Add(navPropertyName, entityReference); entity.FormattedValues.Add(navPropertyName, entityReference.Name); toRemove.AddRange(complements.Select(x => x.Key).ToArray()); } var formattedValueAttributeKeys = attributes.Keys .Where(x => x.EndsWith("@OData.Community.Display.V1.FormattedValue", StringComparison.OrdinalIgnoreCase)) .Except(toRemove) .ToArray(); foreach (var key in formattedValueAttributeKeys) { entity.FormattedValues.Add(ParseFormatedValueProperty(key), attributes[key]?.ToString()); toRemove.Add(key); } var anyKeys = attributes.Keys.Except(toRemove).ToArray(); // Обходим оставшиеся аттрибуты foreach (var attributeKey in anyKeys) { var attributeValue = attributes[attributeKey]; // Если это вложенный массив других сущностей if (attributeValue is IDictionary <string, object>[] nestedEntitiesAttributes) { var entities = new List <Entity>(); foreach (var nestedEntity in nestedEntitiesAttributes) { try { entities.Add(ReadEntity(nestedEntity, metadata, jsonSerializer)); } #pragma warning disable CA1031 // Do not catch general exception types catch #pragma warning restore CA1031 // Do not catch general exception types { // TODO: FixMe Ignore Parsing Errors } } entity.Attributes.Add(attributeKey, entities); toRemove.Add(attributeKey); continue; } // Если Это вложенная сущность if (attributeValue is JObject expandedEntity) { var relationship = metadata.GetRelationshipMetadata( x => x.ReferencingEntity == entity.LogicalName && (x.ReferencingAttribute == attributeKey || x.ReferencingEntityNavigationPropertyName == attributeKey)); var nestedMd = metadata.GetEntityMetadata(x => x.LogicalName == relationship.ReferencedEntity); var nestedEntity = expandedEntity.ToObject <Entity>(jsonSerializer); if (nestedEntity != null) { nestedEntity.LogicalName = nestedMd.LogicalName; if (nestedEntity.ContainsValue(nestedMd.PrimaryIdAttribute)) { nestedEntity.Id = nestedEntity.GetAttributeValue <Guid>(nestedMd.PrimaryIdAttribute); } // Может уже лежать EntityReference на тот же аттрибут entity.Attributes[attributeKey] = nestedEntity; toRemove.Add(attributeKey); continue; } } // Если это свойства AliasedProperty if (attributeKey.Contains("_value", StringComparison.OrdinalIgnoreCase) || attributeKey.Contains("_x002e_", StringComparison.OrdinalIgnoreCase) || attributeKey.Contains("_x0040_", StringComparison.OrdinalIgnoreCase)) { var newName = FormatAttributeName(attributeKey); entity.Attributes.Add(newName, attributeValue); toRemove.Add(attributeKey); continue; } // Иначе - перекладываем атрибуты entity.Attributes.Add(attributeKey, attributeValue); toRemove.Add(attributeKey); } #if DEBUG var remainsKeys = attributes.Keys.Except(toRemove); #endif return(entity); }