Esempio n. 1
0
        public static void ShouldBe(this ComponentRenderedText componentRenderedText, string expectedHtml)
        {
            var testHtml   = string.Concat(componentRenderedText.Tokens).Trim();
            var diffResult = CreateDiff(expectedHtml, testHtml);

            diffResult.HasDifferences().ShouldBeFalse(CreateValidationErrorMessage(expectedHtml, testHtml, diffResult));
        }
Esempio n. 2
0
        public async Task <ComponentPrerenderResult> PrerenderComponentAsync(ComponentPrerenderingContext prerenderingContext)
        {
            var context          = prerenderingContext.Context;
            var navigationStatus = GetOrCreateNavigationStatus(context);

            if (navigationStatus.Navigated)
            {
                // Avoid creating a circuit host if other component earlier in the pipeline already triggered
                // a navigation request. Instead rendre nothing
                return(new ComponentPrerenderResult(Array.Empty <string>()));
            }
            var circuitHost = GetOrCreateCircuitHost(context, navigationStatus);
            ComponentRenderedText renderResult = default;

            try
            {
                renderResult = await circuitHost.PrerenderComponentAsync(
                    prerenderingContext.ComponentType,
                    prerenderingContext.Parameters);
            }
            catch (NavigationException navigationException)
            {
                // Cleanup the state as we won't need it any longer.
                // Signal callbacks that we don't have to register the circuit.
                await CleanupCircuitState(context, navigationStatus, circuitHost);

                // Navigation was attempted during prerendering.
                if (prerenderingContext.Context.Response.HasStarted)
                {
                    // We can't perform a redirect as the server already started sending the response.
                    // This is considered an application error as the developer should buffer the response until
                    // all components have rendered.
                    throw new InvalidOperationException("A navigation command was attempted during prerendering after the server already started sending the response. " +
                                                        "Navigation commands can not be issued during server-side prerendering after the response from the server has started. Applications must buffer the" +
                                                        "reponse and avoid using features like FlushAsync() before all components on the page have been rendered to prevent failed navigation commands.", navigationException);
                }

                context.Response.Redirect(navigationException.Location);
                return(new ComponentPrerenderResult(Array.Empty <string>()));
            }

            circuitHost.Descriptors.Add(new ComponentDescriptor
            {
                ComponentType = prerenderingContext.ComponentType,
                Prerendered   = true
            });

            var result = (new[] {
                $"<!-- M.A.C.Component:{{\"circuitId\":\"{circuitHost.CircuitId}\",\"rendererId\":\"{circuitHost.Renderer.Id}\",\"componentId\":\"{renderResult.ComponentId}\"}} -->",
            }).Concat(renderResult.Tokens).Concat(
                new[] {
                $"<!-- M.A.C.Component: {renderResult.ComponentId} -->"
            });

            return(new ComponentPrerenderResult(result));
        }
        public async Task <IEnumerable <string> > PrerenderComponentAsync(
            ParameterCollection parameters,
            HttpContext httpContext,
            Type componentType)
        {
            var dispatcher = Renderer.CreateDefaultDispatcher();

            InitializeUriHelper(httpContext);
            var loggerFactory = (ILoggerFactory)httpContext.RequestServices.GetService(typeof(ILoggerFactory));

            using (var htmlRenderer = new HtmlRenderer(httpContext.RequestServices, loggerFactory, dispatcher, _encoder.Encode))
            {
                ComponentRenderedText result = default;
                try
                {
                    result = await dispatcher.InvokeAsync(() => htmlRenderer.RenderComponentAsync(
                                                              componentType,
                                                              parameters));
                }
                catch (NavigationException navigationException)
                {
                    // Navigation was attempted during prerendering.
                    if (httpContext.Response.HasStarted)
                    {
                        // We can't perform a redirect as the server already started sending the response.
                        // This is considered an application error as the developer should buffer the response until
                        // all components have rendered.
                        throw new InvalidOperationException("A navigation command was attempted during prerendering after the server already started sending the response. " +
                                                            "Navigation commands can not be issued during server-side prerendering after the response from the server has started. Applications must buffer the" +
                                                            "reponse and avoid using features like FlushAsync() before all components on the page have been rendered to prevent failed navigation commands.", navigationException);
                    }

                    httpContext.Response.Redirect(navigationException.Location);
                    return(Array.Empty <string>());
                }

                return(result.Tokens);
            }
        }