private static void PrepareUrlPathBuilder(
            JsonApiSerializer jsonApiSerializer,
            HttpRequestMessage request,
            JsonApiConfiguration config,
            ApiResource resource)
        {
            var result = config.UrlPathBuilder;
            if (resource == null)
            {
                result = result ?? new DefaultUrlPathBuilder();
            }
            else if (!request.Properties.ContainsKey("MS_RequestContext"))
            {
                result = result ?? new DefaultUrlPathBuilder();
            }
            else
            {
                var routeTemplate = (request.Properties["MS_RequestContext"] as HttpRequestContext)
                    ?.RouteData.Route.RouteTemplate;
                result = result ?? new DefaultUrlPathBuilder(
                    routeTemplate, resource);
            }

            jsonApiSerializer.UrlPathBuilder = result;
        }
 internal JsonApiMediaTypeFormatter(
     HttpRequestMessage request,
     JsonApiConfiguration config)
     : this(config)
 {
     _request = request;
 }
        internal static PreprocessResult PreprocessRequest(
            object content,
            HttpRequestMessage request,
            JsonApiConfiguration config)
        {
            var jsonApi = new JsonApiSerializer();
            jsonApi.JsonConverters.AddRange(config.JsonConverters);

            PrepareQueryContext(jsonApi, request, config);

            ApiResource resource = null;
            if (request.Properties.ContainsKey(Constants.RequestPropertyName))
            {
                resource = (ApiResource)request.Properties[Constants.RequestPropertyName];
            }
            else if (content != null && !(content is HttpError))
            {
                content = new JsonApiException(
                    ErrorType.Server,
                    "You must add a [ReturnsResourceAttribute] to action methods.")
                {
                    HelpLink = "https://github.com/joukevandermaas/saule/wiki"
                };
            }

            PrepareUrlPathBuilder(jsonApi, request, config);

            return jsonApi.PreprocessContent(content, resource, request.RequestUri);
        }
        /// <summary>
        /// Sets up serialization and deserialization of Json Api resources.
        /// </summary>
        /// <param name="config">The <see cref="HttpConfiguration"/> that is used in the setup of the application.</param>
        /// <param name="jsonApiConfiguration">Configuration parameters for Json Api serialization.</param>
        /// <param name="overwriteOtherFormatters">
        /// If true, other formatters will be cleared. Otherwise, the JSON API formatter
        /// will be inserted at the start of the collection.
        /// </param>
        public static void ConfigureJsonApi(
            this HttpConfiguration config,
            JsonApiConfiguration jsonApiConfiguration,
            bool overwriteOtherFormatters)
        {
            config.MessageHandlers.Add(new PreprocessingDelegatingHandler(jsonApiConfiguration));
            var formatter = new JsonApiMediaTypeFormatter(jsonApiConfiguration);

            if (overwriteOtherFormatters)
            {
                config.Formatters.Clear();
                config.Formatters.Add(formatter);
            }
            else
            {
                config.Formatters.Insert(0, formatter);
            }
        }
        internal NewSetupJsonApiServer(JsonApiConfiguration config)
        {
            var httpConfig = new HttpConfiguration();
            if (config == null)
            {
                httpConfig.ConfigureJsonApi();
            }
            else
            {
                httpConfig.ConfigureJsonApi(config);
            }

            httpConfig.MapHttpAttributeRoutes(new DefaultDirectRouteProvider());

            _server = TestServer.Create(builder =>
            {
                builder.UseWebApi(httpConfig);
            });
        }
        private static void PrepareUrlPathBuilder(
            JsonApiSerializer jsonApiSerializer,
            HttpRequestMessage request,
            JsonApiConfiguration config)
        {
            if (config.UrlPathBuilder != null)
            {
                jsonApiSerializer.UrlPathBuilder = config.UrlPathBuilder;
            }
            else if (!request.Properties.ContainsKey(Constants.WebApiRequestContextPropertyName))
            {
                jsonApiSerializer.UrlPathBuilder = new DefaultUrlPathBuilder();
            }
            else
            {
                var requestContext = request.Properties[Constants.WebApiRequestContextPropertyName]
                    as HttpRequestContext;
                var routeTemplate = requestContext?.RouteData.Route.RouteTemplate;
                var virtualPathRoot = requestContext?.VirtualPathRoot ?? "/";

                jsonApiSerializer.UrlPathBuilder = new DefaultUrlPathBuilder(
                    virtualPathRoot, routeTemplate);
            }
        }
 internal JsonApiMediaTypeFormatter(JsonApiConfiguration config)
 {
     SupportedMediaTypes.Add(new MediaTypeHeaderValue(Constants.MediaType));
     _config = config;
 }
 /// <summary>
 /// Sets up serialization and deserialization of Json Api resources.
 /// </summary>
 /// <param name="config">The <see cref="HttpConfiguration"/> that is used in the setup of the application.</param>
 /// <param name="jsonApiConfiguration">Configuration parameters for Json Api serialization.</param>
 public static void ConfigureJsonApi(this HttpConfiguration config, JsonApiConfiguration jsonApiConfiguration)
 {
     config.MessageHandlers.Add(new PreprocessingDelegatingHandler(jsonApiConfiguration));
     config.Formatters.Clear();
     config.Formatters.Add(new JsonApiMediaTypeFormatter(jsonApiConfiguration));
 }
 public ResourceSerializer(JsonSerializer serializer = null, JsonApiConfiguration config = null, IUrlPathBuilder urlBuilder = null)
 {
     _serializer = serializer ?? new JsonSerializer { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
     _config = config ?? new JsonApiConfiguration();
     _urlBuilder = urlBuilder ?? new DefaultUrlPathBuilder();
 }
 public PreprocessingDelegatingHandler(JsonApiConfiguration config)
 {
     _config = config;
 }
        private static void PrepareQueryContext(
            JsonApiSerializer jsonApiSerializer,
            HttpRequestMessage request,
            JsonApiConfiguration config)
        {
            if (!request.Properties.ContainsKey(Constants.QueryContextPropertyName))
            {
                return;
            }

            var queryContext = (QueryContext)request.Properties[Constants.QueryContextPropertyName];

            if (queryContext.Filtering != null)
            {
                queryContext.Filtering.QueryFilters = config.QueryFilterExpressions;
            }

            jsonApiSerializer.QueryContext = queryContext;
        }
        public async Task UsesQueryFilterExpression()
        {
            var config = new JsonApiConfiguration();
            config.QueryFilterExpressions.SetExpression<string>((left, right) => left != right);

            using (var server = new NewSetupJsonApiServer(config))
            {
                var client = server.GetClient();
                var result = await client.GetJsonResponseAsync("api/query/people?filter[last-name]=Russel");
                _output.WriteLine(result.ToString());

                var names = ((JArray)result["data"])
                    .Select(p => p["attributes"]["last-name"].Value<string>())
                    .ToList();

                var filtered = names.Where(a => a != "Russel").ToList();

                Assert.Equal(filtered.Count, names.Count);
            }

        }
        public async Task BuilderAndConverterConstructor()
        {
            var config = new JsonApiConfiguration
            {
                UrlPathBuilder = new CanonicalUrlPathBuilder(),
                JsonConverters = { new StringEnumConverter() }
            };

            using (var server = new NewSetupJsonApiServer(config))
            {
                var client = server.GetClient();
                var result = await client.GetJsonResponseAsync("api/companies/456/");
                _output.WriteLine(result.ToString());

                Assert.Equal("National", result["data"]["attributes"]["location"].Value<string>());

                result = await client.GetJsonResponseAsync("api/people/");
                _output.WriteLine(result.ToString());

                var relatedUrl = result["data"][0]["relationships"]["job"]["links"]["related"]
                    .Value<string>();
                Assert.Equal("http://localhost/corporations/456/", relatedUrl);
            }
        }
        public async Task ConverterConstructor()
        {
            var config = new JsonApiConfiguration
            {
                JsonConverters = { new StringEnumConverter() }
            };

            using (var server = new NewSetupJsonApiServer(config))
            {
                var client = server.GetClient();
                var result = await client.GetJsonResponseAsync("api/companies/456/");
                _output.WriteLine(result.ToString());

                Assert.Equal("National", result["data"]["attributes"]["location"].Value<string>());
            }
        }
 /// <summary>
 /// Sets up serialization and deserialization of Json Api resources.
 /// </summary>
 /// <param name="config">The <see cref="HttpConfiguration"/> that is used in the setup of the application.</param>
 /// <param name="jsonApiConfiguration">Configuration parameters for Json Api serialization.</param>
 public static void ConfigureJsonApi(this HttpConfiguration config, JsonApiConfiguration jsonApiConfiguration)
 {
     ConfigureJsonApi(config, jsonApiConfiguration, false);
 }