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)); }
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); } }