public static string ToHtml(this ViewResult result, HttpContext httpContext)
        {
            try
            {
                IRoutingFeature           feature       = httpContext.Features.Get <IRoutingFeature>();
                RouteData                 routeData     = feature.RouteData;
                string                    viewName      = result.ViewName ?? routeData.Values["action"] as string;
                ActionContext             actionContext = new ActionContext(httpContext, routeData, new ControllerActionDescriptor());
                IOptions <MvcViewOptions> options       = httpContext.RequestServices.GetRequiredService <IOptions <MvcViewOptions> >();
                Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelperOptions htmlHelperOptions = options.Value.HtmlHelperOptions;
                Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult   viewEngineResult  = result.ViewEngine?.FindView(actionContext, viewName, true) ?? options.Value.ViewEngines.Select(x => x.FindView(actionContext, viewName, true)).FirstOrDefault(x => x != null);
                Microsoft.AspNetCore.Mvc.ViewEngines.IView view = viewEngineResult.View;
                StringBuilder builder = new StringBuilder();

                using (StringWriter output = new StringWriter(builder))
                {
                    ViewContext viewContext = new ViewContext(actionContext, view, result.ViewData, result.TempData, output, htmlHelperOptions);

                    view
                    .RenderAsync(viewContext)
                    .GetAwaiter()
                    .GetResult();
                }

                return(builder.ToString());
            }
            catch
            {
                return(string.Empty);
            }
        }
        public void Attribute_Behaves_As_Expected(IRoutingFeature wrongRouting, [Frozen] IRoutingFeature routing, HttpContext context, IHttpContextAccessor accessor)
        {
            Assert.NotSame(wrongRouting, routing);
            Assert.IsAssignableFrom <DefaultHttpContext>(context);
            Assert.Same(routing, context.Features[typeof(IRoutingFeature)]);
            Assert.Same(routing, accessor.HttpContext.Features[typeof(IRoutingFeature)]);
            routing.RouteData.Values.Add("foo", "bar");

            Assert.Equal("bar", accessor.HttpContext.GetRouteValue("foo"));
        }
        public void Customize_EmptyList_WhenRouteValueIsMissing([Frozen] IRoutingFeature routing,
                                                                RouteBasedRoleCusomizer customizer,
                                                                string[] allowedRoles, string routeValue)
        {
            customizer.IncludeOriginals = true;
            routing.RouteData.Values.Add("differentName", routeValue);

            List <string>?result = customizer.CustomizeRoles(allowedRoles).ToList();

            Assert.Empty(result);
        }
        public void Customize_ShouldReturnOriginals_WhenFlagNotSet([Frozen] IRoutingFeature routing,
                                                                   RouteBasedRoleCusomizer customizer,
                                                                   string[] allowedRoles, string routeValue)
        {
            customizer.IncludeOriginals = false;
            routing.RouteData.Values.Add(customizer.RouteName, routeValue);
            List <string>?result = customizer.CustomizeRoles(allowedRoles).ToList();

            //Should have only updated roles
            Assert.Equal(allowedRoles.Length, result.Count);

            //No intersection between original roles and customized roles
            Assert.Empty(result.Intersect(allowedRoles));
        }
        /// <summary>
        /// Gets the page name as a readable string.
        /// </summary>
        /// <param name="routing">The <see cref="IRoutingFeature"/> instance.</param>
        /// <returns>A readable string form of the page name, if available; otherwise, <c>null</c>.</returns>
        public static string GetPageName(this IRoutingFeature routing)
        {
            if (routing == null)
            {
                return(null);
            }

            var attributeRouteHandler = routing.RouteData.Routers.OfType <MvcAttributeRouteHandler>().FirstOrDefault();

            if (attributeRouteHandler?.Actions.FirstOrDefault() is ControllerActionDescriptor action)
            {
                return($"{action.ControllerName}.{action.ActionName}");
            }
            return(attributeRouteHandler?.Actions.FirstOrDefault()?.DisplayName);
        }
        public void Customize_ShouldReturnOriginals_WhenFlagSet([Frozen] IRoutingFeature routing,
                                                                RouteBasedRoleCusomizer customizer,
                                                                string[] allowedRoles, string routeValue)
        {
            customizer.IncludeOriginals = true;
            routing.RouteData.Values.Add(customizer.RouteName, routeValue);

            List <string>?result = customizer.CustomizeRoles(allowedRoles).ToList();

            //Should have double the roles
            Assert.Equal(allowedRoles.Length * 2, result.Count);

            //All original roles are in there.
            Assert.Equal(allowedRoles.Length, result.Intersect(allowedRoles).Count());
        }
Esempio n. 7
0
        private RouteData SetupRouteData(string controllerName = Controller, string actionName = Action)
        {
            _fhirRequestContext.RouteName.Returns((string)null);

            var routeData = new RouteData();

            routeData.Values.Add("controller", controllerName);
            routeData.Values.Add("action", actionName);

            IRoutingFeature routingFeature = Substitute.For <IRoutingFeature>();

            routingFeature.RouteData.Returns(routeData);

            _httpContext.Features[typeof(IRoutingFeature)] = routingFeature;

            return(routeData);
        }
Esempio n. 8
0
        public async Task <string> RenderPartialViewToString <T>(T dataModel, string partialViewPath)
        {
            // we need action context that we will use to find given view path and to construct view context...
            IRoutingFeature routingFeature = httpAccessor.HttpContext.Features.Get <IRoutingFeature>();
            ActionContext   actionContext  = new ActionContext(httpAccessor.HttpContext, routingFeature.RouteData, new ActionDescriptor());

            ViewEngineResult viewEngineResult = razorEngine.FindView(actionContext, partialViewPath, false);
            IView            view;

            if (viewEngineResult.Success)
            {
                view = viewEngineResult.View;
            }
            else
            {
                // view not found ... throw exception with paths that were searched...
                ViewEngineResult     getViewResult = razorEngine.GetView(null, partialViewPath, false);
                IEnumerable <string> searchedPaths = getViewResult.SearchedLocations.Concat(viewEngineResult.SearchedLocations);
                string errorMessage = string.Join(Environment.NewLine, new[] { $"Unable to find view '{ partialViewPath }'. The following locations were searched:" }.Concat(searchedPaths));;
                throw new InvalidOperationException(errorMessage);
            }

            using (StringWriter writer = new StringWriter())
            {
                // create view context that can be used for redering it later...
                ViewContext viewContext = new ViewContext(
                    actionContext,
                    view,
                    new ViewDataDictionary <T>(new EmptyModelMetadataProvider(), new ModelStateDictionary())
                {
                    Model = dataModel     // view data... this is our model that will be used to populate the view.
                },
                    new TempDataDictionary(actionContext.HttpContext, tempDataProvider),
                    writer, // text writer.
                    options.Value.HtmlHelperOptions
                    );

                // render the view now using view context that will populate the string writer.
                await view.RenderAsync(viewContext);

                return(writer.ToString());
            }
        }
        /// <summary>
        /// Gets the route as a readable string.
        /// </summary>
        /// <param name="routing">The <see cref="IRoutingFeature"/> instance.</param>
        /// <returns>A readable string form of the route, if available; otherwise, <c>null</c>.</returns>
        public static string GetRouteString(this IRoutingFeature routing)
        {
            if (routing == null)
            {
                return(null);
            }

            var templateRoute = routing.RouteData.Routers.OfType <Route>().FirstOrDefault();

            if (templateRoute != null)
            {
                if (routing.RouteData.Values.TryGetValue("controller", out var controller) &&
                    routing.RouteData.Values.TryGetValue("action", out var action))
                {
                    return($"{controller}.{action}");
                }
            }

            var attributeRoute = routing.RouteData.Routers.OfType <MvcAttributeRouteHandler>().FirstOrDefault();

            return(attributeRoute?.Actions.FirstOrDefault()?.AttributeRouteInfo?.Template);
        }
Esempio n. 10
0
        /// <summary>
        /// Helper method to get the odata path for an arbitrary odata uri.
        /// </summary>
        /// <param name="request">The request instance in current context</param>
        /// <param name="uri">OData uri</param>
        /// <returns>The parsed odata path</returns>
#if NETCORE
        public static ODataPath CreateODataPath(this HttpRequest request, Uri uri)
        {
            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }

            // 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();

            foreach (KeyValuePair <Type, object> kvp in request.HttpContext.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(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();
            features[typeof(IHttpResponseFeature)] = new HttpResponseFeature();

            // Create a context from the factory or use the default context.
            HttpContext context = new DefaultHttpContext(features);

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

            // Copy the Uri.
            context.Request.Scheme = uri.Scheme;
            context.Request.Host   = uri.IsDefaultPort ?
                                     new HostString(uri.Host) :
                                     new HostString(uri.Host, uri.Port);
            context.Request.QueryString = new QueryString(uri.Query);
            context.Request.Path        = new PathString(uri.AbsolutePath);

            // Get the existing OData route
            IRoutingFeature routingFeature = context.Features[typeof(IRoutingFeature)] as IRoutingFeature;
            ODataRoute      route          = routingFeature.RouteData.Routers.OfType <ODataRoute>().FirstOrDefault();

            // Attempt to route the new request and extract the path.
            RouteContext routeContext = new RouteContext(context);

            route.RouteAsync(routeContext).Wait();
            return(context.Request.ODataFeature().Path);
        }