public void Basics_Work() { // Arrange var env = new Mock <IWebHostEnvironment>(); env.SetupGet(e => e.ContentRootPath).Returns(@"Y:\test\中文"); var options = Options.Create(new NextjsStaticHostingOptions { RootPath = "a/ê" }); var fileProvider = new Mock <IFileProvider>(); fileProvider .Setup(f => f.GetDirectoryContents(string.Empty)) .Returns(new TestDirectoryContents(new TestFile("abc.html"), new TestFile("d&f.html"), new TestFile("[id].html"), new TestDirectory("nested 中文"))); fileProvider .Setup(f => f.GetDirectoryContents("/nested 中文")) .Returns(new TestDirectoryContents(new TestFile("123.html"), new TestFile("[...slug].html"), new TestFile("234.jpg"))); var fileProviderFactory = new Mock <FileProviderFactory>(); fileProviderFactory.Setup(f => f.CreateFileProvider(@"Y:\test\中文\a/ê")).Returns(fileProvider.Object); var staticFileOptionsProvider = new StaticFileOptionsProvider(env.Object, fileProviderFactory.Object, options); var appBuilder = new Mock <IApplicationBuilder>(); appBuilder.Setup(a => a.Build()).Returns(_ => Task.CompletedTask); var endpointRouteBuilder = new Mock <IEndpointRouteBuilder>(); endpointRouteBuilder .Setup(e => e.CreateApplicationBuilder()) .Returns(appBuilder.Object); var sut = new NextjsEndpointDataSource(endpointRouteBuilder.Object, staticFileOptionsProvider); // Act var endpoints = sut.Endpoints; // Assert endpoints.Count.Should().Be(5); endpoints[0].DisplayName.Should().Be("Next.js /abc.html"); endpoints[0].Metadata.GetMetadata <NextjsEndpointDataSource.StaticFileEndpointMetadata>().Path.Should().Be("/abc.html"); GetPatternString(endpoints[0]).Should().Be("abc"); endpoints[1].DisplayName.Should().Be("Next.js /d&f.html"); endpoints[1].Metadata.GetMetadata <NextjsEndpointDataSource.StaticFileEndpointMetadata>().Path.Should().Be("/d&f.html"); GetPatternString(endpoints[1]).Should().Be("d&f"); endpoints[2].DisplayName.Should().Be("Next.js /[id].html"); endpoints[2].Metadata.GetMetadata <NextjsEndpointDataSource.StaticFileEndpointMetadata>().Path.Should().Be("/[id].html"); GetPatternString(endpoints[2]).Should().Be("{id}"); endpoints[3].DisplayName.Should().Be("Next.js /nested 中文/123.html"); endpoints[3].Metadata.GetMetadata <NextjsEndpointDataSource.StaticFileEndpointMetadata>().Path.Should().Be("/nested 中文/123.html"); GetPatternString(endpoints[3]).Should().Be("nested 中文/123"); endpoints[4].DisplayName.Should().Be("Next.js /nested 中文/[...slug].html"); endpoints[4].Metadata.GetMetadata <NextjsEndpointDataSource.StaticFileEndpointMetadata>().Path.Should().Be("/nested 中文/[...slug].html"); GetPatternString(endpoints[4]).Should().Be("nested 中文/{*slug}");
/// <summary> /// Registers endpoints for Next.js pages found in the configured <see cref="NextjsStaticHostingOptions.RootPath"/>. /// This ensures that the correct static Next.js pages will be served at the right paths. /// <para> /// For example, say your client application is composed of the following files: /// <list type="bullet"> /// <item><c>/post/create.html</c></item> /// <item><c>/post/[pid].html</c></item> /// <item><c>/post/[...slug].html</c></item> /// </list> /// </para> /// <para> /// The following routes will be created accordingly: /// <list type="bullet"> /// <item><c>post/create</c>, serving file <c>/post/create.html</c></item> /// <item><c>post/{pid}</c>, serving file <c>/post/[pid].html</c></item> /// <item><c>post/{*slug}</c>, serving file <c>/post/[...slug].html</c></item> /// </list> /// </para> /// <para> /// ASP .NET Core Endpoint Routing built-in route precedence rules ensure the same semantics as Next.js expects will apply. /// E.g., <c>post/create</c> has higher precedence than <c>post/{pid}</c>, which in turn has higher precedence than <c>post/{*slug}</c>. /// </para> /// </summary> /// <example> /// <code> /// <![CDATA[ /// public void Configure(IApplicationBuilder app) /// { /// app.UseRouting(); /// app.UseEndpoints(endpoints => /// { /// endpoints.MapNextjsStaticHtmls(); /// }); /// /// app.UseNextjsStaticHosting(); /// } /// ]]> /// </code> /// </example> public static void MapNextjsStaticHtmls(this IEndpointRouteBuilder endpoints) { _ = endpoints ?? throw new ArgumentNullException(nameof(endpoints)); var staticFileOptionsProvider = endpoints.ServiceProvider.GetRequiredService <StaticFileOptionsProvider>(); var dataSource = new NextjsEndpointDataSource(endpoints, staticFileOptionsProvider); endpoints.DataSources.Add(dataSource); }