Пример #1
0
        private OperationContainer ParseForCreateOrUpdateResourceOperation(AtomicOperationObject operation, OperationKind kind)
        {
            ResourceObject resourceObject = GetRequiredSingleDataForResourceOperation(operation);

            AssertElementHasType(resourceObject, "data");
            AssertElementHasIdOrLid(resourceObject, "data", kind != OperationKind.CreateResource);

            ResourceContext primaryResourceContext = GetExistingResourceContext(resourceObject.Type);

            AssertCompatibleId(resourceObject, primaryResourceContext.IdentityType);

            if (operation.Ref != null)
            {
                // For resource update, 'ref' is optional. But when specified, it must match with 'data'.

                AssertElementHasType(operation.Ref, "ref");
                AssertElementHasIdOrLid(operation.Ref, "ref", true);

                ResourceContext resourceContextInRef = GetExistingResourceContext(operation.Ref.Type);

                if (resourceContextInRef != primaryResourceContext)
                {
                    throw new JsonApiSerializationException("Resource type mismatch between 'ref.type' and 'data.type' element.",
                                                            $"Expected resource of type '{resourceContextInRef.PublicName}' in 'data.type', instead of '{primaryResourceContext.PublicName}'.",
                                                            atomicOperationIndex: AtomicOperationIndex);
                }

                AssertSameIdentityInRefData(operation, resourceObject);
            }

            var request = new JsonApiRequest
            {
                Kind = EndpointKind.AtomicOperations,
#pragma warning disable CS0618 // Type or member is obsolete
                BasePath = _request.BasePath,
#pragma warning restore CS0618 // Type or member is obsolete
                PrimaryResource = primaryResourceContext,
                OperationKind   = kind
            };

            _request.CopyFrom(request);

            IIdentifiable primaryResource = ParseResourceObject(operation.SingleData);

            _resourceDefinitionAccessor.OnDeserialize(primaryResource);

            request.PrimaryId = primaryResource.StringId;
            _request.CopyFrom(request);

            var targetedFields = new TargetedFields
            {
                Attributes    = _targetedFields.Attributes.ToHashSet(),
                Relationships = _targetedFields.Relationships.ToHashSet()
            };

            AssertResourceIdIsNotTargeted(targetedFields);

            return(new OperationContainer(kind, primaryResource, targetedFields, request));
        }
Пример #2
0
        private OperationContainer ParseForRelationshipOperation(AtomicOperationObject operation, OperationKind kind,
                                                                 bool requireToMany)
        {
            AssertElementHasType(operation.Ref, "ref");
            AssertElementHasIdOrLid(operation.Ref, "ref", true);

            var primaryResourceContext = GetExistingResourceContext(operation.Ref.Type);

            AssertCompatibleId(operation.Ref, primaryResourceContext.IdentityType);

            var primaryResource = ResourceFactory.CreateInstance(primaryResourceContext.ResourceType);

            primaryResource.StringId = operation.Ref.Id;
            primaryResource.LocalId  = operation.Ref.Lid;

            var relationship = GetExistingRelationship(operation.Ref, primaryResourceContext);

            if (requireToMany && relationship is HasOneAttribute)
            {
                throw new JsonApiSerializationException(
                          $"Only to-many relationships can be targeted in '{operation.Code.ToString().Camelize()}' operations.",
                          $"Relationship '{operation.Ref.Relationship}' must be a to-many relationship.",
                          atomicOperationIndex: AtomicOperationIndex);
            }

            var secondaryResourceContext = ResourceContextProvider.GetResourceContext(relationship.RightType);

            var request = new JsonApiRequest
            {
                Kind              = EndpointKind.AtomicOperations,
                BasePath          = _request.BasePath,
                PrimaryId         = primaryResource.StringId,
                PrimaryResource   = primaryResourceContext,
                SecondaryResource = secondaryResourceContext,
                Relationship      = relationship,
                IsCollection      = relationship is HasManyAttribute,
                OperationKind     = kind
            };

            _request.CopyFrom(request);

            _targetedFields.Relationships.Add(relationship);

            ParseDataForRelationship(relationship, secondaryResourceContext, operation, primaryResource);

            var targetedFields = new TargetedFields
            {
                Attributes    = _targetedFields.Attributes.ToHashSet(),
                Relationships = _targetedFields.Relationships.ToHashSet()
            };

            return(new OperationContainer(kind, primaryResource, targetedFields, request));
        }