/// <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())); }
/// <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); }
/// <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)); }
public bool TryResolve(string name, out IContract contract) { if (_defaultResolver.TryResolve(name, out contract)) { return(true); } return(_unknownContractResolver.TryResolve(typeof(UnknownResource), out contract)); }
/// <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)); }
/// <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); }
/// <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); }
public bool TryResolve(Type type, out IContract contract) { return(_defaultResolver.TryResolve(type, out contract)); }