Esempio n. 1
0
        public static JsonApiCollectionDocument CreateDocumentFromApiResource <T>(IEnumerable data, string baseUrl = null) where T : JsonApiResource
        {
            var apiResource = Activator.CreateInstance <T>();
            var document    = new JsonApiCollectionDocument();

            document.FromApiResource(data, apiResource, baseUrl);
            return(document);
        }
        private async Task WriteJsonOutputAsync(
            [NotNull] HttpResponse context,
            [NotNull] Encoding selectedEncoding,
            [CanBeNull] object modelData,
            [NotNull] Type modelDataType,
            [NotNull] JsonApiResource modelResource,
            [CanBeNull] QueryInfo queryInfo)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (selectedEncoding == null)
            {
                throw new ArgumentNullException(nameof(selectedEncoding));
            }
            if (modelDataType == null)
            {
                throw new ArgumentNullException(nameof(modelDataType));
            }
            if (modelResource == null)
            {
                throw new ArgumentNullException(nameof(modelResource));
            }

            var meta = new JsonApiMetaData();

            if (modelData is IQueryResult queryResult)
            {
                meta.PageCount   = queryResult.PageCount;
                meta.RecordCount = queryResult.RecordCount;
                modelData        = queryResult.Data;
            }

            IJsonApiDocument document;

            if (modelData is IEnumerable collectionValue)
            {
                var apiCollectionDocument = new JsonApiCollectionDocument();
                apiCollectionDocument.FromApiResource(collectionValue, modelResource);
                document = apiCollectionDocument;
            }
            else
            {
                var apiDocument = new JsonApiDocument();
                apiDocument.FromApiResource(modelData, modelResource);
                document = apiDocument;
            }

            document.Meta = meta;

            if (queryInfo?.Includes != null)
            {
                foreach (var include in queryInfo.Includes)
                {
                    document.IncludeRelation(modelResource, modelData, include);
                }
            }

            var serializer = JsonSerializer.Create(JsonSerializerSettings);

            using (var streamWriter = new StreamWriter(context.Body, selectedEncoding))
            {
                serializer.Serialize(streamWriter, document, document.GetType());
                await streamWriter.FlushAsync();
            }
        }
        /// <inheritdoc/>
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var result = await base.SendAsync(request, cancellationToken);

            if (!(request.Properties.TryGetValue(nameof(JsonApiAttribute.ReturnResourceGetter), out var resourceUntyped) && resourceUntyped is JsonApiResource resource))
            {
                return(result);
            }

            if (!result.IsSuccessStatusCode)
            {
                return(result);
            }

            if (!(result.Content is ObjectContent objectContent))
            {
                return(result);
            }

            var meta = new JsonApiMetaData();

            BenchmarkCollection benchmarks = null;

            if (request.Properties.TryGetValue(nameof(BenchmarkCollection), out var benchmarksObj) &&
                benchmarksObj is BenchmarkCollection foundBenchmarks)
            {
                benchmarks = foundBenchmarks;
            }

            try
            {
                Func <string> serializeDocument;

                using (benchmarks.CreateBenchmark("ConvertToJsonApiDoc"))
                {
                    string overridePrimaryType = null;

                    var value = objectContent.Value;
                    if (value is IJsonApiOverridePrimaryType jsonApiOverridePrimaryType)
                    {
                        value = jsonApiOverridePrimaryType.Data;
                        overridePrimaryType = jsonApiOverridePrimaryType.Type;
                    }
                    if (value is IQueryResult queryResult)
                    {
                        meta.PageCount   = queryResult.PageCount;
                        meta.RecordCount = queryResult.RecordCount;
                        value            = queryResult.Data;
                    }

                    IJsonApiDocument document;
                    if (value is IEnumerable collectionValue)
                    {
                        var apiCollectionDocument = new JsonApiCollectionDocument();
                        apiCollectionDocument.FromApiResource(collectionValue, resource);
                        if (overridePrimaryType != null)
                        {
                            foreach (var primaryDataEntry in apiCollectionDocument.Data)
                            {
                                primaryDataEntry.Type = overridePrimaryType;
                            }
                        }
                        document          = apiCollectionDocument;
                        serializeDocument = () => JsonConvert.SerializeObject(apiCollectionDocument, Config.Formatter.SerializerSettings);
                    }
                    else
                    {
                        var apiDocument = new JsonApiDocument();
                        apiDocument.FromApiResource(value, resource);
                        if (overridePrimaryType != null)
                        {
                            apiDocument.Data.Type = overridePrimaryType;
                        }
                        document          = apiDocument;
                        serializeDocument = () => JsonConvert.SerializeObject(apiDocument, Config.Formatter.SerializerSettings);
                    }

                    if (request.Properties.TryGetValue(nameof(QueryInfo), out var queryInfoUntyped) && queryInfoUntyped is QueryInfo queryInfo && queryInfo.Includes != null)
                    {
                        foreach (var include in queryInfo.Includes)
                        {
                            document.IncludeRelation(resource, value, include);
                        }
                    }

                    document.Meta = meta;
                }

                meta.Benchmarks = benchmarks?.Benchmarks?.Select(b => $"{b.Name}:{b.Duration}");
#if DEBUG
                var benchmarkSerialization = new BenchmarkCollection();
                using (benchmarkSerialization.CreateBenchmark("Serialization"))
                {
#endif
                result.Content = new StringContent(serializeDocument(), Encoding.UTF8, "application/vnd.api+json");
#if DEBUG
            }
            foreach (var benchmark in benchmarkSerialization.Benchmarks)
            {
                Debug.WriteLine($"{benchmark.Name} took {benchmark.Duration} ms");
            }
#endif

                return(result);
            }
            catch (Exception e)
            {
                return(e.ToJsonApiErrorResponseMessage());
            }
        }