/// <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)})"); }
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); }
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); }
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()); }
/// <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)})"); }
public EntityConverter(IWebApiMetadataService metadata) { _metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); }
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)); }
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); }