Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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());
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }