/// <summary>
        /// Serialize the value.
        /// </summary>
        /// <param name="serializer">The serializer to utilize when serializing nested objects.</param>
        /// <param name="type">The CLR type of the value to serialize.</param>
        /// <param name="value">The value to serialize.</param>
        /// <returns>The JSON value that represents the given CLR value.</returns>
        public JsonValue SerializeValue(IJsonSerializer serializer, Type type, object value)
        {
            if (_contractResolver.TryResolve(type, out var contract) == false)
            {
                throw new HypermediaJsonException($"Could not resolve a contract for {type}.");
            }

            return(new JsonObject(SerializeMembers(serializer, contract, value).Where(IsNotNull).ToList()));
        }
Exemple #2
0
        /// <summary>
        /// Attempt to patch the given entity.
        /// </summary>
        /// <param name="entity">The entity to apply the patch to.</param>
        /// <param name="contractResolver">The contract resolver to use.</param>
        /// <returns>true if the entity could be patched, false if not.</returns>
        public bool TryPatch(T entity, IContractResolver contractResolver)
        {
            try
            {
                if (contractResolver.TryResolve(typeof(T), out IContract contract) == false)
                {
                    return(false);
                }

                var serializer = new JsonSerializer(
                    new JsonConverterFactory(
                        JsonConverterFactory.Default,
                        new ContractConverter(ContractResolver, _fieldNamingStratgey),
                        new ComplexConverter(_fieldNamingStratgey)));

                var converter = new ContractConverter(contractResolver, _fieldNamingStratgey);
                converter.DeserializeObject(serializer, (JsonObject)_jsonValue, contract, entity);

                return(true);
            }
            // ReSharper disable once EmptyGeneralCatchClause
            catch { }

            return(false);
        }
Exemple #3
0
        /// <summary>
        /// Attempt to patch the given entity.
        /// </summary>
        /// <param name="entity">The entity to apply the patch to.</param>
        /// <param name="contractResolver">The contract resolver to use.</param>
        /// <returns>true if the entity could be patched, false if not.</returns>
        public bool TryPatch(T entity, IContractResolver contractResolver)
        {
            try
            {
                var jsonObject = _jsonValue["data"] as JsonObject;

                var typeAttribute = jsonObject?["type"];
                if (typeAttribute == null)
                {
                    return(false);
                }

                IContract contract;
                if (contractResolver.TryResolve(((JsonString)typeAttribute).Value, out contract) == false)
                {
                    return(false);
                }

                var serializer = new JsonApiSerializer(contractResolver, _fieldNamingStratgey);
                serializer.DeserializeEntity(contract, jsonObject, entity);

                return(true);
            }
            // ReSharper disable once EmptyGeneralCatchClause
            catch { }

            return(false);
        }
        /// <summary>
        /// Returns a value indicating whether or not the given type can be resolved.
        /// </summary>
        /// <param name="resolver">The contract resolver to perform the operation on.</param>
        /// <param name="type">The CLR type to test whether it can be resolved.</param>
        /// <returns>true if the given CLR type can be resolved, false if not.</returns>
        public static bool CanResolve(this IContractResolver resolver, Type type)
        {
            if (resolver == null)
            {
                throw new ArgumentNullException(nameof(resolver));
            }

            return(resolver.TryResolve(type, out IContract resourceContract));
        }
Exemple #5
0
            public bool TryResolve(string name, out IContract contract)
            {
                if (_defaultResolver.TryResolve(name, out contract))
                {
                    return(true);
                }

                return(_unknownContractResolver.TryResolve(typeof(UnknownResource), out contract));
            }
Exemple #6
0
        /// <summary>
        /// Attempt to resolve the contract that is represented in the JSON object.
        /// </summary>
        /// <param name="contractResolver">The contract resolver to use.</param>
        /// <param name="jsonObject">The JSON object that contains the contract definition.</param>
        /// <param name="contract">The contract that was resolved.</param>
        /// <returns>true if the contract could be resolved, false if not.</returns>
        bool TryResolveContact(IContractResolver contractResolver, JsonObject jsonObject, out IContract contract)
        {
            var typeAttribute = jsonObject?["type"];

            if (typeAttribute == null)
            {
                contract = null;
                return(false);
            }

            return(contractResolver.TryResolve(((JsonString)typeAttribute).Value, out contract));
        }
        /// <summary>
        /// Resolve the inverse relationship.
        /// </summary>
        /// <param name="relationship">The relationship to resolve the inverse from.</param>
        /// <param name="contractResolver">The contract resolver that contains the nessessary contracts for resolution.</param>
        /// <returns>The inverse relationship.</returns>
        public static IRelationship Inverse(this IRelationship relationship, IContractResolver contractResolver)
        {
            if (relationship == null)
            {
                throw new ArgumentNullException(nameof(relationship));
            }

            if (String.IsNullOrWhiteSpace(relationship.InverseName) || contractResolver.TryResolve(relationship.RelatedTo, out IContract other) == false)
            {
                return(null);
            }

            return(other.Relationship(relationship.InverseName));
        }
Exemple #8
0
        /// <summary>
        /// Asynchronously executes the binding for the given request.
        /// </summary>
        /// <param name="metadataProvider">Metadata provider to use for validation.</param>
        /// <param name="actionContext">The action context for the binding. The action context contains the parameter dictionary that will get populated with the parameter.</param>
        /// <param name="cancellationToken">Cancellation token for cancelling the binding operation.</param>
        /// <returns>A task object representing the asynchronous operation.</returns>
        public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            if (_contractResolver.TryResolve(_resourceType, out var root) == false)
            {
                return(Task.FromResult(0));
            }

            var type = typeof(JsonApiRequestMetadata <>).MakeGenericType(_resourceType);

            var constructor = type.GetConstructor(new[] { typeof(IContractResolver), typeof(IContract), typeof(HttpRequestMessage) });

            Debug.Assert(constructor != null);

            actionContext.ActionArguments[Descriptor.ParameterName] = constructor.Invoke(new object[] { _contractResolver, root, actionContext.Request });

            return(Task.FromResult(0));
        }
        /// <inheritdoc />
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            if (_contractResolver.TryResolve(bindingContext.ModelType.GenericTypeArguments[0], out var root) == false)
            {
                return(Task.CompletedTask);
            }

            var type = typeof(JsonApiRequestMetadata <>).MakeGenericType(bindingContext.ModelType.GenericTypeArguments[0]);

            var constructor = type.GetConstructor(new[] { typeof(IContractResolver), typeof(IContract), typeof(HttpRequest) });

            Debug.Assert(constructor != null);

            bindingContext.Result = ModelBindingResult.Success(constructor.Invoke(new object[] { _contractResolver, root, bindingContext.HttpContext.Request }));

            return(Task.CompletedTask);
        }
Exemple #10
0
        /// <summary>
        /// Attempt to resolve a realtionship from the given name and path.
        /// </summary>
        /// <param name="root">The root level contract to resolve the relationship from.</param>
        /// <param name="name">The name of the relationship to resolve.</param>
        /// <param name="path">The path for to resolve on the relationship.</param>
        /// <param name="memberPath">The path that was resolved, or undefined if no path could be found.</param>
        /// <returns>true if the path was resolved correctly, false if not.</returns>
        bool TryResolveRelationship(IContract root, string name, string path, ref MemberPath memberPath)
        {
            var relationship = root.Relationship(name);

            if (relationship == null)
            {
                memberPath = null;
                return(false);
            }

            if (_contractResolver.TryResolve(relationship.RelatedTo, out root) == false)
            {
                memberPath = null;
                return(false);
            }

            if (TryResolve(root, path, ref memberPath) == false)
            {
                return(false);
            }

            memberPath = new MemberPath(relationship, memberPath);
            return(true);
        }
Exemple #11
0
 public bool TryResolve(Type type, out IContract contract)
 {
     return(_defaultResolver.TryResolve(type, out contract));
 }