示例#1
0
        /// <summary>
        /// Convert EntityReference to WebApi NavigationUrl
        /// </summary>
        /// <param name="entityReference">EntityReference</param>
        /// <param name="organizationMetadata">Instance metadata store</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">When EntityReference is null</exception>
        public static string ToNavigationLink(this EntityReference entityReference,
                                              IWebApiMetadataService organizationMetadata)
        {
            if (entityReference is null)
            {
                throw new ArgumentNullException(nameof(entityReference));
            }

            var logicalName    = entityReference.LogicalName;
            var collectionName = organizationMetadata.GetEntitySetName(logicalName);

            // If alternate keys not present
            if (entityReference.KeyAttributes.Any() != true)
            {
                return($"{collectionName}({entityReference.Id})");
            }

            // Else If alternate keys present
            var keysPairList = new List <string>();

            foreach (var(key, value) in entityReference.KeyAttributes)
            {
                if (value is int)
                {
                    keysPairList.Add($"{key}={value}");
                }
                else
                {
                    keysPairList.Add($"{key}='{value}'");
                }
            }

            return($"{collectionName}({string.Join("&", keysPairList)})");
        }
示例#2
0
        public CrmWebApiClient(HttpClient httpClient, IWebApiMetadataService webApiMetadata,
                               ILogger <CrmWebApiClient> logger)
        {
            HttpClient     = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
            WebApiMetadata = webApiMetadata ?? throw new ArgumentNullException(nameof(webApiMetadata));
            _logger        = logger ?? throw new ArgumentNullException(nameof(logger));

            SerializerSettings.Converters.Add(new EntityConverter(webApiMetadata));
            SerializerSettings.Converters.Add(new EntityCollectionConverter(webApiMetadata));
            SerializerSettings.Converters.Add(new EntityReferenceConverter(webApiMetadata));

            _serializer = JsonSerializer.Create(SerializerSettings);
        }
示例#3
0
        public static string FormatPropertyToLogicalName(this IWebApiMetadataService metadata, string entityLogicalName,
                                                         string propertyLogicalName)
        {
            if (metadata == null)
            {
                throw new ArgumentNullException(nameof(metadata));
            }

            var relationship = metadata.GetRelationshipMetadata(x =>
                                                                string.Equals(x.ReferencingEntity, entityLogicalName, StringComparison.OrdinalIgnoreCase) &&
                                                                string.Equals(x.ReferencingAttribute, propertyLogicalName, StringComparison.OrdinalIgnoreCase));

            return(relationship != null ? $"_{propertyLogicalName}_value" : propertyLogicalName);
        }
示例#4
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());
        }
示例#5
0
        /// <summary>
        /// Convert EntityReference to WebApi NavigationUrl
        /// </summary>
        /// <param name="entityReference">EntityReference</param>
        /// <param name="organizationMetadata">Instance metadata store</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">When EntityReference is null</exception>
        public static string ToNavigationLink(this EntityReference entityReference,
                                              IWebApiMetadataService organizationMetadata)
        {
            if (entityReference is null)
            {
                throw new ArgumentNullException(nameof(entityReference));
            }

            var logicalName    = entityReference.LogicalName;
            var collectionName = organizationMetadata.GetEntitySetName(logicalName);

            // If alternate keys not present
            if (entityReference.KeyAttributes.Any() != true)
            {
                return($"{collectionName}({entityReference.Id})");
            }

            // Else If alternate keys present
            var keys = entityReference.KeyAttributes
                       .Select(kvp => $"{kvp.Key}='{kvp.Value}'");

            return($"{collectionName}({string.Join("&", keys)})");
        }
示例#6
0
 public EntityConverter(IWebApiMetadataService metadata)
 {
     _metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
 }
示例#7
0
 public static EntityMetadata GetEntityMetadata(this IWebApiMetadataService metadata,
                                                [AllowNull] string logicalName)
 {
     if (logicalName is null)
     {
         return(default);
 public static string ToNavigationLink(this Entity entity, IWebApiMetadataService organizationMetadata)
 {
     return(entity.ToEntityReference().ToNavigationLink(organizationMetadata));
 }
示例#9
0
 internal string BuildQueryString(IWebApiMetadataService webApiMetadata, in string entityName)
        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);
        }