/// <summary>
        /// Find default static files by context and pipeline.
        /// </summary>
        /// <param name="actionContext"></param>
        /// <param name="pipeline"></param>
        /// <returns></returns>
        protected virtual DefaultStaticFiles GetDefaultStaticFiles(ActionContext actionContext,
                                                                   IReusablePipeline pipeline)
        {
            var           controllerActionDescriptor = actionContext.ActionDescriptor as ControllerActionDescriptor;
            List <string> noStaticFileTypes          = null;

            if (controllerActionDescriptor != null)
            {
                var methodAttributes = controllerActionDescriptor.MethodInfo
                                       .GetCustomAttributes <NoDefaultStaticFilesAttribute>()?.ToList();
                if (methodAttributes?.Any() == true)
                {
                    noStaticFileTypes = methodAttributes.Where(t => t.FileTypes != null).SelectMany(t => t.FileTypes)
                                        .ToList();
                }
                else
                {
                    var controllerAttributes = controllerActionDescriptor.ControllerTypeInfo
                                               .GetCustomAttributes <NoDefaultStaticFilesAttribute>()?.ToList();
                    if (controllerAttributes?.Any() == true)
                    {
                        noStaticFileTypes = controllerAttributes.Where(t => t.FileTypes != null)
                                            .SelectMany(t => t.FileTypes).ToList();
                    }
                }
            }
            var controllerName = (actionContext.RouteData.Values["controller"] as string)?.ToLower();
            var viewName       = (actionContext.HttpContext.Items[_options.Value.ViewNameHttpContextItemKey] as string)
                                 ?.ToLower();
            var defaultStaticFileLocations = new List <string>();

            if (pipeline != null)
            {
                var pipelinePath = _pipelineDecisionTree.GetPipelinePath(pipeline);
                defaultStaticFileLocations.AddRange(pipelinePath.SelectMany(p =>
                                                                            p.GetStaticFilesRelativeLocations(actionContext, viewName)));
            }
            if (!string.IsNullOrEmpty(_options.Value.DefaultStaticFileLocation))
            {
                defaultStaticFileLocations.Add($"{controllerName}/{viewName}");
            }
            var f         = new DefaultStaticFiles();
            var fileTypes = new[] { "css", "js" };

            foreach (var type in fileTypes)
            {
                foreach (var l in defaultStaticFileLocations.Select(t1 => t1.Replace("//", "/").ToLower()))
                {
                    if (noStaticFileTypes?.Contains(type) != true &&
                        _fileProvider.GetFileInfo($"wwwroot/{type}/{l}{_minifySuffix}.{type}").Exists)
                    {
                        f[type] = $"/{type}/{l}{_minifySuffix}.{type}";
                        break;
                    }
                }
            }
            return(f);
        }
        public virtual async Task Invoke(HttpContext httpContext)
        {
            var       deepestDepth = 0;
            IPipeline pipeline     = null;

            if (_pipelineCollectionAccessor.Pipelines?.Any() == true)
            {
                foreach (var p in _pipelineCollectionAccessor.Pipelines)
                {
                    if (await p.ResolveAsync(httpContext))
                    {
                        var depth = _decisionTree.GetPipelinePath(p).Count;
                        if (depth > deepestDepth)
                        {
                            pipeline     = p;
                            deepestDepth = depth;
                        }
                    }
                }
            }
            if (pipeline != null)
            {
                httpContext.Items[_options.Value.PipelineHttpContextItemKey] = pipeline;
                _logger.LogInformation(InformationEventId, $"Resolved pipeline: {pipeline.Name}");
                var requestDelegate = _pipelines.GetOrAdd(pipeline,
                                                          new Lazy <RequestDelegate>(() =>
                {
                    var builder = _app.New();
                    Task.WaitAll(pipeline.ConfigurePipeline(builder));
                    builder.Run(_next);
                    return(builder.Build());
                }));
                await requestDelegate.Value(httpContext);
            }
            else
            {
                if (_defaultRequestDelegate == null && _defaultPipelineConfiguration != null)
                {
                    var builder = _app.New();
                    _defaultPipelineConfiguration(builder);
                    builder.Run(_next);
                    _defaultRequestDelegate = builder.Build();
                }
                await(_defaultRequestDelegate ?? _next)(httpContext);
            }
        }
 /// <inheritdoc />
 /// <summary>
 /// <para>The cases of controller and view part in view location are case sensitive, and same as the original name.</para>
 /// <para>e.g. The part of 'ProductController' in view location is 'Product'</para>
 /// <para>e.g. The part of view name 'Partial/Index' in view location is 'Partial/Index'</para>
 /// </summary>
 public virtual IEnumerable <string> ExpandViewLocations(ViewLocationExpanderContext context,
                                                         IEnumerable <string> viewLocations)
 {
     if (context.ActionContext.HttpContext.GetPipeline() is IReusablePipeline pipeline)
     {
         var pipelinePath = _pipelineDecisionTree.GetPipelinePath(pipeline);
         //main view
         var tmpViewLocations = pipelinePath.SelectMany(p => p.GetSharedViewLocations(context)).ToList();
         if (!string.IsNullOrEmpty(_options.Value.DefaultViewLocation))
         {
             tmpViewLocations.Add(_options.Value.DefaultViewLocation);
         }
         //shared view
         tmpViewLocations.AddRange(pipelinePath.SelectMany(t => t.GetSharedViewLocations(context)));
         if (!string.IsNullOrEmpty(_options.Value.DefaultLayoutLocation))
         {
             tmpViewLocations.Add(_options.Value.DefaultLayoutLocation);
         }
         viewLocations = tmpViewLocations.Concat(viewLocations).Distinct();
     }
     return(viewLocations);
 }
예제 #4
0
        public virtual void ChangeRouteDataToLocatedAction(RouteContext context, ReusablePipeline pipeline)
        {
            var uri            = context.HttpContext.Request.Path.Value.Trim('/');
            var controllerName = context.RouteData.Values["controller"].ToString();
            var targetPipeline = _pipelineActions.GetOrAdd(pipeline,
                                                           t => new ConcurrentDictionary <string, ConcurrentDictionary <string, IPipeline> >(StringComparer.OrdinalIgnoreCase))
                                 .GetOrAdd(controllerName, t => new ConcurrentDictionary <string, IPipeline>(StringComparer.OrdinalIgnoreCase))
                                 .GetOrAdd(uri, t1 =>
            {
                var pipelinePath = _pipelineDecisionTree.GetPipelinePath(pipeline);
                foreach (var p in pipelinePath)
                {
                    var fullControllerNames = p.GetControllerFullnames(context);
                    foreach (var fullControllerName in fullControllerNames)
                    {
                        if (_controllerActionUris.TryGetValue(fullControllerName, out var uris))
                        {
                            if (uris.Contains(uri, StringComparer.OrdinalIgnoreCase))
                            {
                                return(p);
                            }
                        }
                    }
                }
                return(null);
            });

            if (string.IsNullOrEmpty(targetPipeline?.Name))
            {
                context.RouteData.Values.Remove(_options.Value.PipelineNameRouteDataKey);
            }
            else
            {
                context.RouteData.Values[_options.Value.PipelineNameRouteDataKey] = targetPipeline.Name.ToLower();
            }
        }