Exemplo n.º 1
0
        public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            // The goal of this method is to perform the final matching:
            // Map between route values matched by the template and the ones we want to expose to the action for binding.
            // (tweaking the route values is fine here)
            // Invalidating the candidate if the key/function values are not valid/missing.
            // Perform overload resolution for functions by looking at the candidates and their metadata.
            for (var i = 0; i < candidates.Count; i++)
            {
                ref CandidateState candidate = ref candidates[i];
                if (!candidates.IsValidCandidate(i))
                {
                    continue;
                }

                IODataRoutingMetadata metadata = candidate.Endpoint.Metadata.OfType <IODataRoutingMetadata>().FirstOrDefault();
                if (metadata == null)
                {
                    continue;
                }

                IHttpMethodMetadata httpMetadata = candidate.Endpoint.Metadata.GetMetadata <IHttpMethodMetadata>();
                if (httpMetadata == null)
                {
                    // Check the http method
                    if (metadata.HttpMethods != null && !metadata.HttpMethods.Contains(httpContext.Request.Method))
                    {
                        candidates.SetValidity(i, false);
                        continue;
                    }
                }

                ODataTemplateTranslateContext translatorContext =
                    new ODataTemplateTranslateContext(httpContext, candidate.Values, metadata.Model);

                try
                {
                    ODataPath odataPath = _translator.Translate(metadata.Template, translatorContext);
                    if (odataPath != null)
                    {
                        IODataFeature odataFeature = httpContext.ODataFeature();
                        odataFeature.PrefixName = metadata.Prefix;
                        odataFeature.Model      = metadata.Model;
                        odataFeature.Path       = odataPath;
                    }
                    else
                    {
                        candidates.SetValidity(i, false);
                    }
                }
                catch (Exception)
                {
                    candidates.SetValidity(i, false);
                }
            }
        /// <summary>
        /// Applies the policy to the CandidateSet.
        /// </summary>
        /// <param name="httpContext">The context associated with the current request.</param>
        /// <param name="candidates">The CandidateSet.</param>
        /// <returns>The task.</returns>
        public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
        {
            if (httpContext == null)
            {
                throw Error.ArgumentNull(nameof(httpContext));
            }

            IODataFeature odataFeature = httpContext.ODataFeature();

            if (odataFeature.Path != null)
            {
                // If we have the OData path setting, it means there's some Policy working.
                // Let's skip this default OData matcher policy.
                return(Task.CompletedTask);
            }

            // The goal of this method is to perform the final matching:
            // Map between route values matched by the template and the ones we want to expose to the action for binding.
            // (tweaking the route values is fine here)
            // Invalidating the candidate if the key/function values are not valid/missing.
            // Perform overload resolution for functions by looking at the candidates and their metadata.
            for (var i = 0; i < candidates.Count; i++)
            {
                ref CandidateState candidate = ref candidates[i];
                if (!candidates.IsValidCandidate(i))
                {
                    continue;
                }

                IODataRoutingMetadata metadata = candidate.Endpoint.Metadata.OfType <IODataRoutingMetadata>().FirstOrDefault();
                if (metadata == null)
                {
                    continue;
                }

                if (odataFeature.Path != null)
                {
                    // If it's odata endpoint, and we have a path set, let other odata endpoints invalid.
                    candidates.SetValidity(i, false);
                    continue;
                }

                ODataTemplateTranslateContext translatorContext =
                    new ODataTemplateTranslateContext(httpContext, candidate.Endpoint, candidate.Values, metadata.Model);

                ODataPath odataPath = _translator.Translate(metadata.Template, translatorContext);
                if (odataPath != null)
                {
                    odataFeature.RoutePrefix = metadata.Prefix;
                    odataFeature.Model       = metadata.Model;
                    odataFeature.Path        = odataPath;

                    MergeRouteValues(translatorContext.UpdatedValues, candidate.Values);

                    // Shall we break the remaining candidates?
                    // So far the answer is no. Because we can use this matcher to obsolete the unmatched endpoint.
                    // break;
                }
                else
                {
                    candidates.SetValidity(i, false);
                }
            }
Exemplo n.º 3
0
        public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            IODataFeature odataFeature = httpContext.ODataFeature();

            if (odataFeature.Path != null)
            {
                // If we have the OData path setting, it means there's some Policy working.
                // Let's skip this default OData matcher policy.
                return(Task.CompletedTask);
            }

            for (var i = 0; i < candidates.Count; i++)
            {
                ref CandidateState candidate = ref candidates[i];
                if (!candidates.IsValidCandidate(i))
                {
                    continue;
                }

                IODataRoutingMetadata metadata = candidate.Endpoint.Metadata.OfType <IODataRoutingMetadata>().FirstOrDefault();
                if (metadata == null)
                {
                    continue;
                }

                // Get api-version query from HttpRequest?
                QueryStringApiVersionReader reader = new QueryStringApiVersionReader("api-version");
                string apiVersionStr = reader.Read(httpContext.Request);
                if (apiVersionStr == null)
                {
                    candidates.SetValidity(i, false);
                    continue;
                }
                ApiVersion apiVersion = ApiVersion.Parse(apiVersionStr);

                IEdmModel model = GetEdmModel(apiVersion);
                if (model == null)
                {
                    candidates.SetValidity(i, false);
                    continue;
                }

                if (!IsApiVersionMatch(candidate.Endpoint.Metadata, apiVersion))
                {
                    candidates.SetValidity(i, false);
                    continue;
                }

                ODataTemplateTranslateContext translatorContext
                    = new ODataTemplateTranslateContext(httpContext, candidate.Endpoint, candidate.Values, model);

                try
                {
                    ODataPath odataPath = _translator.Translate(metadata.Template, translatorContext);
                    if (odataPath != null)
                    {
                        odataFeature.RoutePrefix = metadata.Prefix;
                        odataFeature.Model       = model;
                        odataFeature.Path        = odataPath;

                        ODataOptions options = new ODataOptions();
                        UpdateQuerySetting(options);
                        options.AddRouteComponents(model);
                        odataFeature.Services = options.GetRouteServices(string.Empty);

                        MergeRouteValues(translatorContext.UpdatedValues, candidate.Values);
                    }
                    else
                    {
                        candidates.SetValidity(i, false);
                    }
                }
                catch
                {
                    candidates.SetValidity(i, false);
                }
            }