Пример #1
0
        /// <summary>
        /// 获取指定URL的功能信息
        /// </summary>
        public static IFunction GetFunction(this ControllerBase controller, string url)
        {
            url = url.StartsWith("https://") || url.StartsWith("http://")
                ? new Uri(url).AbsolutePath : !url.StartsWith("/") ? $"/{url}" : url;
            IServiceProvider    provider    = controller.HttpContext.RequestServices;
            IHttpContextFactory factory     = provider.GetService <IHttpContextFactory>();
            HttpContext         httpContext = factory.Create(controller.HttpContext.Features);

            httpContext.Request.Path   = url;
            httpContext.Request.Method = "POST";
            RouteContext     routeContext = new RouteContext(httpContext);
            IRouteCollection router       = controller.RouteData.Routers.OfType <IRouteCollection>().FirstOrDefault();

            if (router == null)
            {
                return(null);
            }
            router.RouteAsync(routeContext).Wait();
            if (routeContext.Handler == null)
            {
                return(null);
            }
            RouteValueDictionary dict       = routeContext.RouteData.Values;
            string           areaName       = dict.GetOrDefault("area")?.ToString();
            string           controllerName = dict.GetOrDefault("controller")?.ToString();
            string           actionName     = dict.GetOrDefault("action")?.ToString();
            IFunctionHandler handler        = provider.GetService <IFunctionHandler>();

            return(handler?.GetFunction(areaName, controllerName, actionName));
        }
Пример #2
0
        internal RequestState(IHttpRequestFeature requestFeature, IHttpContextFactory factory,
                              IFeatureCollection featureCollection)
        {
            _factory = factory;
            _requestAbortedSource = new CancellationTokenSource();
            _pipelineFinished     = false;

            var contextFeatures = new FeatureCollection(featureCollection);

            contextFeatures.Set(requestFeature);
            _responseFeature = new ResponseFeature {
                Protocol = requestFeature.Protocol
            };
            contextFeatures.Set <IHttpResponseFeature>(_responseFeature);
            var requestLifetimeFeature = new HttpRequestLifetimeFeature();

            contextFeatures.Set <IHttpRequestLifetimeFeature>(requestLifetimeFeature);

            _responseStream                       = new WriteOnlyResponseStream(AbortRequest);
            _responseFeature.Body                 = _responseStream;
            _responseFeature.StatusCode           = 200;
            requestLifetimeFeature.RequestAborted = _requestAbortedSource.Token;

            Context = _factory.Create(contextFeatures);
        }
Пример #3
0
        internal RequestState(IHttpRequestFeature requestFeature, IHttpContextFactory factory,
                              IFeatureCollection featureCollection)
        {
            _factory = factory;
            _requestAbortedSource = new CancellationTokenSource();
            _pipelineFinished     = false;

            var contextFeatures = new FeatureCollection(featureCollection);

            contextFeatures.Set(requestFeature);

            _responseStream  = new WriteOnlyResponseStream(AbortRequest);
            _responseFeature = new ResponseFeature(requestFeature.Protocol, 200, null, _responseStream, new HeaderDictionary())
            {
                Abort = Abort
            };
            contextFeatures.Set <IHttpResponseFeature>(_responseFeature);
            contextFeatures.Set <IHttpResponseBodyFeature>(new StreamResponseBodyFeature(_responseStream));
            var requestLifetimeFeature = new HttpRequestLifetimeFeature();

            contextFeatures.Set <IHttpRequestLifetimeFeature>(requestLifetimeFeature);
            requestLifetimeFeature.RequestAborted = _requestAbortedSource.Token;

            Context = _factory.Create(contextFeatures);
        }
        public HttpContext Create(IFeatureCollection contextFeatures)
        {
            var httpContext = _contextFactory.Create(contextFeatures);

            _configureContextFeatures?.Invoke(contextFeatures, httpContext);

            return(httpContext);
        }
Пример #5
0
        public HttpContext Create(HttpContext context, IUntypedCall call, Encoding requestEncoding)
        {
            var newFeatures = new FeatureCollection(context.Features);

            OverrideRequestDataFeatures(newFeatures, context.Features, call, requestEncoding);
            // NOTE: factory breaks HttpContextAccessor
            var result = httpContextFactory.Create(newFeatures);

            log.LogTrace($"Created HttpContext [{result}]");
            return(result);
        }
Пример #6
0
        public HttpContext Create(IFeatureCollection featureCollection)
        {
            var httpContext = _httpContextFactory.Create(featureCollection);

            if (httpContext.Request.Headers.TryGetValue("ms-cv", out var correlationVector))
            {
                httpContext.Features.Set <ICorrelationVectorFeature>(new CorrelationVectorFeature(correlationVector));
            }
            else
            {
                httpContext.Features.Set <ICorrelationVectorFeature>(new CorrelationVectorFeature());
            }

            return(httpContext);
        }
Пример #7
0
        public async Task <bool> Check(string path, string method)
        {
            IRouteCollection router = RouteData.Routers.OfType <IRouteCollection>().First();

            HttpContext context = _httpContextFactory.Create(HttpContext.Features);

            context.Request.Path   = path;
            context.Request.Method = method;

            var routeContext = new RouteContext(context);
            await router.RouteAsync(routeContext);

            bool exists = routeContext.Handler != null;

            return(exists);
        }
Пример #8
0
        private static HttpContext CreateHttpContext(HttpContext originalContext)
        {
            // Clone the features so that a new set is used for each context.
            // The features themselves will be reused but not the collection. We
            // store the request container as a feature of the request and we don't want
            // the features added to one context/request to be visible on another.
            //
            // Note that just about everything in the HttpContext and HttpRequest is
            // backed by one of these features. So reusing the features means the HttContext
            // and HttpRequests are the same without needing to copy properties. To make them
            // different, we need to avoid copying certain features to that the objects don't
            // share the same storage/
            IFeatureCollection features = new FeatureCollection();
            string             pathBase = "";

            foreach (KeyValuePair <Type, object> kvp in originalContext.Features)
            {
                // Don't include the OData features. They may already
                // be present. This will get re-created later.
                //
                // Also, clear out the items feature, which is used
                // to store a few object, the one that is an issue here is the Url
                // helper, which has an affinity to the context. If we leave it,
                // the context of the helper no longer matches the new context and
                // the resulting url helper doesn't have access to the OData feature
                // because it's looking in the wrong context.
                //
                // Because we need a different request and response, leave those features
                // out as well.
                if (kvp.Key == typeof(IHttpRequestFeature))
                {
                    pathBase = ((IHttpRequestFeature)kvp.Value).PathBase;
                }

                if (kvp.Key == typeof(IODataBatchFeature) ||
                    kvp.Key == typeof(IODataFeature) ||
                    kvp.Key == typeof(IItemsFeature) ||
                    kvp.Key == typeof(IHttpRequestFeature) ||
                    kvp.Key == typeof(IHttpResponseFeature) ||
                    kvp.Key == typeof(IQueryFeature)) // Noted: we should not pass the QueryFeature from Main request to the sub request
                {
                    continue;
                }

                if (kvp.Key == typeof(IEndpointFeature))
                {
                    continue;
                }

                features[kvp.Key] = kvp.Value;
            }

            // Add in an items, request and response feature.
            features[typeof(IItemsFeature)]       = new ItemsFeature();
            features[typeof(IHttpRequestFeature)] = new HttpRequestFeature
            {
                PathBase = pathBase
            };

            features[typeof(IHttpResponseFeature)] = new HttpResponseFeature();

            // Create a context from the factory or use the default context.
            HttpContext         context            = null;
            IHttpContextFactory httpContextFactory = originalContext.RequestServices.GetService <IHttpContextFactory>();

            if (httpContextFactory != null)
            {
                context = httpContextFactory.Create(features);
            }
            else
            {
                context = new DefaultHttpContext(features);
            }

            // Clone parts of the request. All other parts of the request will be
            // populated during batch processing.
            context.Request.Cookies = originalContext.Request.Cookies;
            foreach (KeyValuePair <string, StringValues> header in originalContext.Request.Headers)
            {
                string headerKey = header.Key.ToLowerInvariant();
                // do not copy over headers that should not be inherited from batch to individual requests
                if (!nonInheritableHeaders.Contains(headerKey))
                {
                    // some preferences may be inherited, others discarded
                    if (headerKey == "prefer")
                    {
                        string preferencesToInherit = GetPreferencesToInheritFromBatch(header.Value);
                        if (!string.IsNullOrEmpty(preferencesToInherit))
                        {
                            context.Request.Headers.Add(header.Key, preferencesToInherit);
                        }
                    }
                    // do not copy already existing headers, such as Cookie
                    else if (!context.Request.Headers.ContainsKey(header.Key))
                    {
                        context.Request.Headers.Add(header);
                    }
                }
            }

            // Create a response body as the default response feature does not
            // have a valid stream.
            // Use a special batch stream that remains open after the writer is disposed.
            context.Response.Body = new ODataBatchStream();

            return(context);
        }
Пример #9
0
        public static async Task <IHtmlContent> RenderActionAsync(this HttpContext context, string action, string controller, string area, object?[]?parameters = null, ViewContext?existingViewContext = null)
        {
            if (action is null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            if (controller is null)
            {
                throw new ArgumentNullException(nameof(controller));
            }

            HttpContext currentHttpContext = existingViewContext?.HttpContext ?? context;

            parameters ??= Array.Empty <object>();
            // fetching required services for invocation

            IHttpContextFactory httpContextFactory = GetServiceOrFail <IHttpContextFactory>(currentHttpContext);

            HttpContext newHttpContext = httpContextFactory.Create(currentHttpContext.Features);

            IActionInvokerFactory actionInvokerFactory         = GetServiceOrFail <IActionInvokerFactory>(newHttpContext);
            IActionDescriptorCollectionProvider actionSelector = GetServiceOrFail <IActionDescriptorCollectionProvider>(newHttpContext);

            // creating new action invocation context
            RouteData routeData = new RouteData();

            RouteValueDictionary routeValues = new RouteValueDictionary(new { area, controller, action });

            IRazorViewEngine ViewEngine = GetServiceOrFail <IRazorViewEngine>(newHttpContext);

            newHttpContext.Response.Body = new MemoryStream();

            routeData.PushState(null, routeValues, null);

            Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor = actionSelector.ActionDescriptors.Items.First(i => i.RouteValues["Controller"] == controller && i.RouteValues["Action"] == action);

            ActionContext actionContext = new ActionContext(newHttpContext, routeData, actionDescriptor);

            //We're not invoking this using an invoker beacause it doesn't support as many object types as parameters.
            IControllerFactory cf = GetServiceOrFail <IControllerFactory>(newHttpContext);

            //build the controller
            Controller c = (Controller)cf.CreateController(new ControllerContext(actionContext));

            //call the action to build the information required to fill the view
            ViewResult?viewResult = c.GetType()?.GetMethod(action)?.Invoke(c, parameters) as ViewResult;

            //Find the view the action says it uses
            ViewEngineResult result = ViewEngine.FindView(actionContext, viewResult?.ViewName ?? action, false);

            string htmlContent = string.Empty;

            using (StringWriter output = new StringWriter())
            {
                HtmlHelperOptions options;

                if (existingViewContext != null)
                {
                    options = new HtmlHelperOptions()
                    {
                        ClientValidationEnabled         = existingViewContext.ClientValidationEnabled,
                        Html5DateRenderingMode          = existingViewContext.Html5DateRenderingMode,
                        ValidationSummaryMessageElement = existingViewContext.ValidationSummaryMessageElement,
                        ValidationMessageElement        = existingViewContext.ValidationMessageElement
                    };
                }
                else
                {
                    options = new HtmlHelperOptions()
                    {
                        ClientValidationEnabled         = true,
                        Html5DateRenderingMode          = Html5DateRenderingMode.CurrentCulture,
                        ValidationSummaryMessageElement = "validation-summary-errors",
                        ValidationMessageElement        = "validation-summary-messages"
                    };
                }

                ViewContext viewcontext = new ViewContext(actionContext, result.View, viewResult?.ViewData, viewResult?.TempData, output, options);

                await result.View.RenderAsync(viewcontext).ConfigureAwait(false);

                htmlContent = output.ToString();
            }

            return(new HtmlString(htmlContent));
        }
Пример #10
0
 public HttpContext CreateContext(IFeatureCollection contextFeatures)
 {
     return(_httpContextFactory?.Create(contextFeatures) ?? new DefaultHttpContext(contextFeatures));
 }
Пример #11
0
        private static HttpContext CreateHttpContext(HttpContext originalContext)
        {
            // Clone the features so that a new set is used for each context.
            // The features themselves will be reused but not the collection. We
            // store the request container as a feature of the request and we don't want
            // the features added to one context/request to be visible on another.
            //
            // Note that just about everything inm the HttpContext and HttpRequest is
            // backed by one of these features. So reusing the features means the HttContext
            // and HttpRequests are the same without needing to copy properties. To make them
            // different, we need to avoid copying certain features to that the objects don't
            // share the same storage/
            IFeatureCollection features = new FeatureCollection();
            string             pathBase = "";

            foreach (KeyValuePair <Type, object> kvp in originalContext.Features)
            {
                // Don't include the OData features. They may already
                // be present. This will get re-created later.
                //
                // Also, clear out the items feature, which is used
                // to store a few object, the one that is an issue here is the Url
                // helper, which has an affinity to the context. If we leave it,
                // the context of the helper no longer matches the new context and
                // the resulting url helper doesn't have access to the OData feature
                // because it's looking in the wrong context.
                //
                // Because we need a different request and response, leave those features
                // out as well.
                if (kvp.Key == typeof(IHttpRequestFeature))
                {
                    pathBase = ((IHttpRequestFeature)kvp.Value).PathBase;
                }

                if (kvp.Key == typeof(IODataBatchFeature) ||
                    kvp.Key == typeof(IODataFeature) ||
                    kvp.Key == typeof(IItemsFeature) ||
                    kvp.Key == typeof(IHttpRequestFeature) ||
                    kvp.Key == typeof(IHttpResponseFeature))
                {
                    continue;
                }

                features[kvp.Key] = kvp.Value;
            }

            // Add in an items, request and response feature.
            features[typeof(IItemsFeature)]       = new ItemsFeature();
            features[typeof(IHttpRequestFeature)] = new HttpRequestFeature
            {
                PathBase = pathBase
            };
            features[typeof(IHttpResponseFeature)] = new HttpResponseFeature();

            // Create a context from the factory or use the default context.
            HttpContext         context            = null;
            IHttpContextFactory httpContextFactory = originalContext.RequestServices.GetRequiredService <IHttpContextFactory>();

            if (httpContextFactory != null)
            {
                context = httpContextFactory.Create(features);
            }
            else
            {
                context = new DefaultHttpContext(features);
            }

            // Clone parts of the request. All other parts of the request will be
            // populated during batch processing.
            context.Request.Cookies = originalContext.Request.Cookies;
            foreach (KeyValuePair <string, StringValues> header in originalContext.Request.Headers)
            {
                context.Request.Headers.Add(header);
            }

            // Create a response body as the default response feature does not
            // have a valid stream.
            context.Response.Body = new MemoryStream();

            return(context);
        }
Пример #12
0
        public HttpContext CreateContext(IFeatureCollection contextFeatures)
        {
            var httpContext = _httpContextFactory.Create(contextFeatures);

            return(httpContext);
        }
Пример #13
0
 public HttpContext CreateContext(IFeatureCollection contextFeatures)
 {
     return(_httpContextFactory.Create(contextFeatures));
 }