diff --git a/src/XrmMockup365/Core.cs b/src/XrmMockup365/Core.cs index 8fe3d26d..fe177cce 100644 --- a/src/XrmMockup365/Core.cs +++ b/src/XrmMockup365/Core.cs @@ -1046,7 +1046,12 @@ private OrganizationResponse ExecuteRequest( var handler = RequestHandlers.FirstOrDefault(x => x.HandlesRequest(request.RequestName)); if (handler != null) { - return handler.Execute(request, userRef); + var response = handler.Execute(request, userRef); + if (response != null && string.IsNullOrEmpty(response.ResponseName)) + { + response.ResponseName = request.RequestName; + } + return response; } if (settings.ExceptionFreeRequests?.Contains(request.RequestName) ?? false) diff --git a/src/XrmMockup365/Internal/Utility.cs b/src/XrmMockup365/Internal/Utility.cs index 5ba1638a..15064846 100644 --- a/src/XrmMockup365/Internal/Utility.cs +++ b/src/XrmMockup365/Internal/Utility.cs @@ -1044,6 +1044,61 @@ public static object ConvertValueFromSerializableDTO(TableColumnDTO colToSeriali var newCollection = new OptionSetValueCollection(typed.Values.Select(x => new OptionSetValue(x)).ToList()); return newCollection; } + else if (type == typeof(EntityCollection)) + { + var node = JsonNode.Parse(colToSerialize.Value); + var typed = (EntityCollectionDTO)node.Deserialize(typeof(EntityCollectionDTO)); + + // Manually deserialize entities + var entities = new List(); + if (typed.Entities.ValueKind == JsonValueKind.Array) + { + foreach (var entityElement in typed.Entities.EnumerateArray()) + { + var entity = new Entity(); + + // Deserialize LogicalName + if (entityElement.TryGetProperty("LogicalName", out var logicalNameProp)) + { + entity.LogicalName = logicalNameProp.GetString(); + } + + // Deserialize Id + if (entityElement.TryGetProperty("Id", out var idProp) && idProp.ValueKind == JsonValueKind.String) + { + entity.Id = Guid.Parse(idProp.GetString()); + } + + // Deserialize Attributes + if (entityElement.TryGetProperty("Attributes", out var attributesProp) && attributesProp.ValueKind == JsonValueKind.Array) + { + foreach (var attr in attributesProp.EnumerateArray()) + { + if (attr.TryGetProperty("Key", out var keyProp) && attr.TryGetProperty("Value", out var valueProp)) + { + var key = keyProp.GetString(); + // Recursively deserialize attribute values (could be EntityReference, etc.) + var value = JsonSerializer.Deserialize(valueProp.GetRawText()); + entity[key] = value; + } + } + } + + entities.Add(entity); + } + } + + var newCollection = new EntityCollection(entities) + { + MoreRecords = typed.MoreRecords, + PagingCookie = typed.PagingCookie, + MinActiveRowVersion = typed.MinActiveRowVersion, + TotalRecordCount = typed.TotalRecordCount, + TotalRecordCountLimitExceeded = typed.TotalRecordCountLimitExceeded, + EntityName = typed.EntityName + }; + return newCollection; + } else if (type == typeof(BooleanManagedProperty)) { var node = JsonNode.Parse(colToSerialize.Value); diff --git a/src/XrmMockup365/Serialization/EntityCollectionDTO.cs b/src/XrmMockup365/Serialization/EntityCollectionDTO.cs new file mode 100644 index 00000000..2794b88f --- /dev/null +++ b/src/XrmMockup365/Serialization/EntityCollectionDTO.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.Text.Json; + +namespace DG.Tools.XrmMockup.Serialization +{ + public class EntityCollectionDTO + { + public JsonElement Entities { get; set; } + public bool MoreRecords { get; set; } + public string PagingCookie { get; set; } + public string MinActiveRowVersion { get; set; } + public int TotalRecordCount { get; set; } + public bool TotalRecordCountLimitExceeded { get; set; } + public string EntityName { get; set; } + } +}