├── .gitignore ├── Chapter02 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── Pages │ │ │ └── Counter.razor │ │ ├── Program.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ ├── Home.razor │ │ │ └── Weather.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ └── MyBlog.sln ├── Chapter03 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── Pages │ │ │ └── Counter.razor │ │ ├── Program.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ ├── Home.razor │ │ │ └── Weather.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── EntityFramework │ ├── Data.Tests │ │ ├── BlogApiTestsUsingEntityFramework.cs │ │ ├── Data.Tests.csproj │ │ ├── Data │ │ │ ├── Blogposts │ │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ │ ├── Categories │ │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ │ ├── Comments │ │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ │ └── Tags │ │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ │ ├── DataTestFixture.cs │ │ └── GlobalUsings.cs │ └── Data │ │ ├── BlogApiEntityFrameworkDirectAccess.cs │ │ ├── Data.csproj │ │ ├── Entities │ │ ├── BlogDbContext.cs │ │ ├── BlogPost.cs │ │ ├── Category.cs │ │ ├── Comment.cs │ │ └── Tag.cs │ │ ├── Migrations │ │ ├── 20231109113913_InitialCreate.Designer.cs │ │ ├── 20231109113913_InitialCreate.cs │ │ └── BlogDbContextModelSnapshot.cs │ │ └── Nuget.config │ ├── MyBlog.sln │ └── RavenDb │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ └── Data │ ├── BlogApiRavenDbDirectAccess.cs │ └── Data.csproj ├── Chapter04 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── Pages │ │ │ └── Counter.razor │ │ ├── Program.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.sln │ └── SharedComponents │ ├── Nuget.config │ ├── Pages │ └── Home.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ ├── background.png │ └── exampleJsInterop.js ├── Chapter05 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── Pages │ │ │ └── Counter.razor │ │ ├── Program.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── CounterWithParameterAndEvent.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── ParentCounter.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.sln │ ├── SharedComponents │ ├── ErrorBoundaryDemo │ │ ├── ComponentWithError.razor │ │ ├── CustomErrorBoundaryDemo.razor │ │ └── ErrorBoundaryDemo.razor │ ├── Nuget.config │ ├── Pages │ │ ├── AlertTest.razor │ │ ├── ErrorBoundaryTest.razor │ │ ├── Home.razor │ │ ├── Post.razor │ │ ├── RenderFragmentTest.razor │ │ └── SetFocus.razor │ ├── ReusableComponents │ │ └── Alert.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── background.png │ │ └── exampleJsInterop.js │ └── Snippets │ └── builder.snippet ├── Chapter06 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── Pages │ │ │ ├── Admin │ │ │ │ └── TagList.razor │ │ │ └── Counter.razor │ │ ├── Program.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── CounterWithParameterAndEvent.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── ParentCounter.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.sln │ ├── SharedComponents │ ├── BootstrapFieldCssClassProvider.cs │ ├── CustomCssClassProvider.cs │ ├── ErrorBoundaryDemo │ │ ├── ComponentWithError.razor │ │ ├── CustomErrorBoundaryDemo.razor │ │ └── ErrorBoundaryDemo.razor │ ├── InputTextAreaOnInput.cs │ ├── ItemList.razor │ ├── Nuget.config │ ├── Pages │ │ ├── Admin │ │ │ ├── BlogPostEdit.razor │ │ │ ├── BlogPostList.razor │ │ │ └── CategoryList.razor │ │ ├── AlertTest.razor │ │ ├── Comments.razor │ │ ├── ErrorBoundaryTest.razor │ │ ├── Home.razor │ │ ├── Post.razor │ │ ├── RenderFragmentTest.razor │ │ └── SetFocus.razor │ ├── ReusableComponents │ │ ├── Alert.razor │ │ ├── BlogButton.razor │ │ ├── BlogInputText.razor │ │ └── BlogNavigationLock.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── background.png │ │ └── exampleJsInterop.js │ └── Snippets │ └── builder.snippet ├── Chapter07 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── BlogApiWebClient.cs │ │ ├── Pages │ │ │ ├── Admin │ │ │ │ └── TagList.razor │ │ │ └── Counter.razor │ │ ├── Program.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── CounterWithParameterAndEvent.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── ParentCounter.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Endpoints │ │ ├── BlogPostEndpoints.cs │ │ ├── CategoryEndpoints.cs │ │ ├── CommentEndpoints.cs │ │ └── TagEndpoints.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.sln │ ├── SharedComponents │ ├── BootstrapFieldCssClassProvider.cs │ ├── CustomCssClassProvider.cs │ ├── ErrorBoundaryDemo │ │ ├── ComponentWithError.razor │ │ ├── CustomErrorBoundaryDemo.razor │ │ └── ErrorBoundaryDemo.razor │ ├── InputTextAreaOnInput.cs │ ├── ItemList.razor │ ├── Nuget.config │ ├── Pages │ │ ├── Admin │ │ │ ├── BlogPostEdit.razor │ │ │ ├── BlogPostList.razor │ │ │ └── CategoryList.razor │ │ ├── AlertTest.razor │ │ ├── Comments.razor │ │ ├── ErrorBoundaryTest.razor │ │ ├── Home.razor │ │ ├── Post.razor │ │ ├── RenderFragmentTest.razor │ │ └── SetFocus.razor │ ├── ReusableComponents │ │ ├── Alert.razor │ │ ├── BlogButton.razor │ │ ├── BlogInputText.razor │ │ └── BlogNavigationLock.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── background.png │ │ └── exampleJsInterop.js │ └── Snippets │ └── builder.snippet ├── Chapter08 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── BlogApiWebClient.cs │ │ ├── Pages │ │ │ ├── Admin │ │ │ │ └── TagList.razor │ │ │ └── Counter.razor │ │ ├── PersistentAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── UserInfo.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── CounterWithParameterAndEvent.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── LoginStatus.razor │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── ParentCounter.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Endpoints │ │ ├── BlogPostEndpoints.cs │ │ ├── CategoryEndpoints.cs │ │ ├── CommentEndpoints.cs │ │ └── TagEndpoints.cs │ │ ├── PersistingServerAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.sln │ ├── SharedComponents │ ├── BootstrapFieldCssClassProvider.cs │ ├── CustomCssClassProvider.cs │ ├── ErrorBoundaryDemo │ │ ├── ComponentWithError.razor │ │ ├── CustomErrorBoundaryDemo.razor │ │ └── ErrorBoundaryDemo.razor │ ├── InputTextAreaOnInput.cs │ ├── ItemList.razor │ ├── Nuget.config │ ├── Pages │ │ ├── Admin │ │ │ ├── BlogPostEdit.razor │ │ │ ├── BlogPostList.razor │ │ │ └── CategoryList.razor │ │ ├── AlertTest.razor │ │ ├── Comments.razor │ │ ├── ErrorBoundaryTest.razor │ │ ├── Home.razor │ │ ├── Post.razor │ │ ├── RenderFragmentTest.razor │ │ └── SetFocus.razor │ ├── ReusableComponents │ │ ├── Alert.razor │ │ ├── BlogButton.razor │ │ ├── BlogInputText.razor │ │ └── BlogNavigationLock.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── background.png │ │ └── exampleJsInterop.js │ └── Snippets │ └── builder.snippet ├── Chapter09 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── BlogApiWebClient.cs │ │ ├── Pages │ │ │ ├── Admin │ │ │ │ ├── TagList.razor │ │ │ │ └── TagList.razor.bak │ │ │ └── Counter.razor │ │ ├── PersistentAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── Program.cs.bak │ │ ├── UserInfo.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── CounterWithParameterAndEvent.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── LoginStatus.razor │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── ParentCounter.razor │ │ ├── Routes.razor │ │ ├── Routes.razor.bak │ │ └── _Imports.razor │ │ ├── Endpoints │ │ ├── BlogPostEndpoints.cs │ │ ├── CategoryEndpoints.cs │ │ ├── CommentEndpoints.cs │ │ └── TagEndpoints.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.sln │ ├── SharedComponents │ ├── BootstrapFieldCssClassProvider.cs │ ├── CustomCssClassProvider.cs │ ├── ErrorBoundaryDemo │ │ ├── ComponentWithError.razor │ │ ├── CustomErrorBoundaryDemo.razor │ │ └── ErrorBoundaryDemo.razor │ ├── InputTextAreaOnInput.cs │ ├── ItemList.razor │ ├── Nuget.config │ ├── Pages │ │ ├── Admin │ │ │ ├── BlogPostEdit.razor │ │ │ ├── BlogPostList.razor │ │ │ └── CategoryList.razor │ │ ├── AlertTest.razor │ │ ├── Comments.razor │ │ ├── ErrorBoundaryTest.razor │ │ ├── Home.razor │ │ ├── Post.razor │ │ ├── RenderFragmentTest.razor │ │ └── SetFocus.razor │ ├── ReusableComponents │ │ ├── Alert.razor │ │ ├── BlogButton.razor │ │ ├── BlogInputText.razor │ │ └── BlogNavigationLock.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── background.png │ │ ├── bootstrap.min.css │ │ └── exampleJsInterop.js │ └── Snippets │ └── builder.snippet ├── Chapter10 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── BlogApiWebClient.cs │ │ ├── Pages │ │ │ ├── Admin │ │ │ │ └── TagList.razor │ │ │ └── Counter.razor │ │ ├── PersistentAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── UserInfo.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── CounterWithParameterAndEvent.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── LoginStatus.razor │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── ParentCounter.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Endpoints │ │ ├── BlogPostEndpoints.cs │ │ ├── CategoryEndpoints.cs │ │ ├── CommentEndpoints.cs │ │ └── TagEndpoints.cs │ │ ├── PersistingServerAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.sln │ ├── SharedComponents │ ├── BootstrapFieldCssClassProvider.cs │ ├── CustomCssClassProvider.cs │ ├── Demo │ │ ├── HighChart.razor │ │ ├── HighChart.razor.js │ │ ├── HighChartTest.razor │ │ ├── JSInteropSamples │ │ │ ├── JSToReferenceNET.razor │ │ │ ├── JSToReferenceNET.razor.js │ │ │ ├── JSToStaticNET.razor │ │ │ ├── JSToStaticNET.razor.js │ │ │ ├── NetToJS.razor │ │ │ └── NetToJS.razor.js │ │ └── JSInteropSamplesWasm │ │ │ ├── JSToStaticNET.razor │ │ │ ├── JSToStaticNET.razor.cs │ │ │ ├── JSToStaticNET.razor.js │ │ │ ├── NetToJS.razor │ │ │ ├── NetToJS.razor.cs │ │ │ └── NetToJS.razor.js │ ├── ErrorBoundaryDemo │ │ ├── ComponentWithError.razor │ │ ├── CustomErrorBoundaryDemo.razor │ │ └── ErrorBoundaryDemo.razor │ ├── InputTextAreaOnInput.cs │ ├── ItemList.razor │ ├── Nuget.config │ ├── Pages │ │ ├── Admin │ │ │ ├── BlogPostEdit.razor │ │ │ ├── BlogPostList.razor │ │ │ └── CategoryList.razor │ │ ├── AlertTest.razor │ │ ├── Comments.razor │ │ ├── ErrorBoundaryTest.razor │ │ ├── Home.razor │ │ ├── Post.razor │ │ ├── RenderFragmentTest.razor │ │ └── SetFocus.razor │ ├── ReusableComponents │ │ ├── Alert.razor │ │ ├── BlogButton.razor │ │ ├── BlogButton.razor.js │ │ ├── BlogInputText.razor │ │ └── BlogNavigationLock.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── background.png │ │ ├── bootstrap.min.css │ │ └── exampleJsInterop.js │ └── Snippets │ └── builder.snippet ├── Chapter11 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── BlogApiWebClient.cs │ │ ├── Pages │ │ │ ├── Admin │ │ │ │ └── TagList.razor │ │ │ └── Counter.razor │ │ ├── PersistentAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── Services │ │ │ ├── BlazorWebAssemblyBlogNotificationService.cs │ │ │ └── BlogBrowserStorage.cs │ │ ├── UserInfo.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── CounterWithParameterAndEvent.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── LoginStatus.razor │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── ParentCounter.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Endpoints │ │ ├── BlogPostEndpoints.cs │ │ ├── CategoryEndpoints.cs │ │ ├── CommentEndpoints.cs │ │ └── TagEndpoints.cs │ │ ├── Hubs │ │ └── BlogNotificationHub.cs │ │ ├── PersistingServerAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Services │ │ ├── BlazorServerBlogNotificationService.cs │ │ └── BlogProtectedBrowserStorage.cs │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.sln │ ├── RootLevelCascadingValueDemo │ ├── RootLevelCascadingValueDemo.Client │ │ ├── CascadingValueDemo.razor │ │ ├── Pages │ │ │ └── Counter.razor │ │ ├── Preferences.cs │ │ ├── Program.cs │ │ ├── RootLevelCascadingValueDemo.Client.csproj │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ └── RootLevelCascadingValueDemo │ │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ ├── Home.razor │ │ │ └── Weather.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── RootLevelCascadingValueDemo.csproj │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── SharedComponents │ ├── BootstrapFieldCssClassProvider.cs │ ├── CustomCssClassProvider.cs │ ├── Demo │ │ ├── HighChart.razor │ │ ├── HighChart.razor.js │ │ ├── HighChartTest.razor │ │ ├── JSInteropSamples │ │ │ ├── JSToReferenceNET.razor │ │ │ ├── JSToReferenceNET.razor.js │ │ │ ├── JSToStaticNET.razor │ │ │ ├── JSToStaticNET.razor.js │ │ │ ├── NetToJS.razor │ │ │ └── NetToJS.razor.js │ │ └── JSInteropSamplesWasm │ │ │ ├── JSToStaticNET.razor │ │ │ ├── JSToStaticNET.razor.cs │ │ │ ├── JSToStaticNET.razor.js │ │ │ ├── NetToJS.razor │ │ │ ├── NetToJS.razor.cs │ │ │ └── NetToJS.razor.js │ ├── ErrorBoundaryDemo │ │ ├── ComponentWithError.razor │ │ ├── CustomErrorBoundaryDemo.razor │ │ └── ErrorBoundaryDemo.razor │ ├── InputTextAreaOnInput.cs │ ├── Interfaces │ │ ├── IBlogNotificationService.cs │ │ └── IBrowserStorage.cs │ ├── ItemList.razor │ ├── Nuget.config │ ├── Pages │ │ ├── Admin │ │ │ ├── BlogPostEdit.razor │ │ │ ├── BlogPostList.razor │ │ │ └── CategoryList.razor │ │ ├── AlertTest.razor │ │ ├── Comments.razor │ │ ├── ErrorBoundaryTest.razor │ │ ├── Home.razor │ │ ├── Post.razor │ │ ├── RenderFragmentTest.razor │ │ └── SetFocus.razor │ ├── ReusableComponents │ │ ├── Alert.razor │ │ ├── BlogButton.razor │ │ ├── BlogButton.razor.js │ │ ├── BlogInputText.razor │ │ └── BlogNavigationLock.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── background.png │ │ ├── bootstrap.min.css │ │ └── exampleJsInterop.js │ └── Snippets │ └── builder.snippet ├── Chapter12 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── BlogApiWebClient.cs │ │ ├── Pages │ │ │ ├── Admin │ │ │ │ └── TagList.razor │ │ │ └── Counter.razor │ │ ├── PersistentAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── Services │ │ │ ├── BlazorWebAssemblyBlogNotificationService.cs │ │ │ └── BlogBrowserStorage.cs │ │ ├── UserInfo.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── CounterWithParameterAndEvent.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── LoginStatus.razor │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── ParentCounter.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Endpoints │ │ ├── BlogPostEndpoints.cs │ │ ├── CategoryEndpoints.cs │ │ ├── CommentEndpoints.cs │ │ └── TagEndpoints.cs │ │ ├── Hubs │ │ └── BlogNotificationHub.cs │ │ ├── PersistingServerAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Services │ │ ├── BlazorServerBlogNotificationService.cs │ │ └── BlogProtectedBrowserStorage.cs │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── BlazorWebAssemblyApp │ ├── App.razor │ ├── BlazorWebAssemblyApp.csproj │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── Pages │ │ ├── Counter.razor │ │ ├── Home.razor │ │ ├── ThrowException.razor │ │ └── Weather.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ └── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── favicon.png │ │ ├── icon-192.png │ │ ├── index.html │ │ └── sample-data │ │ └── weather.json │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.sln │ ├── SharedComponents │ ├── BootstrapFieldCssClassProvider.cs │ ├── CustomCssClassProvider.cs │ ├── Demo │ │ ├── HighChart.razor │ │ ├── HighChart.razor.js │ │ ├── HighChartTest.razor │ │ ├── JSInteropSamples │ │ │ ├── JSToReferenceNET.razor │ │ │ ├── JSToReferenceNET.razor.js │ │ │ ├── JSToStaticNET.razor │ │ │ ├── JSToStaticNET.razor.js │ │ │ ├── NetToJS.razor │ │ │ └── NetToJS.razor.js │ │ └── JSInteropSamplesWasm │ │ │ ├── JSToStaticNET.razor │ │ │ ├── JSToStaticNET.razor.cs │ │ │ ├── JSToStaticNET.razor.js │ │ │ ├── NetToJS.razor │ │ │ ├── NetToJS.razor.cs │ │ │ └── NetToJS.razor.js │ ├── ErrorBoundaryDemo │ │ ├── ComponentWithError.razor │ │ ├── CustomErrorBoundaryDemo.razor │ │ └── ErrorBoundaryDemo.razor │ ├── InputTextAreaOnInput.cs │ ├── Interfaces │ │ ├── IBlogNotificationService.cs │ │ └── IBrowserStorage.cs │ ├── ItemList.razor │ ├── Nuget.config │ ├── Pages │ │ ├── Admin │ │ │ ├── BlogPostEdit.razor │ │ │ ├── BlogPostList.razor │ │ │ └── CategoryList.razor │ │ ├── AlertTest.razor │ │ ├── Comments.razor │ │ ├── ErrorBoundaryTest.razor │ │ ├── Home.razor │ │ ├── Post.razor │ │ ├── RenderFragmentTest.razor │ │ ├── SetFocus.razor │ │ └── ThrowException.razor │ ├── ReusableComponents │ │ ├── Alert.razor │ │ ├── BlogButton.razor │ │ ├── BlogButton.razor.js │ │ ├── BlogInputText.razor │ │ └── BlogNavigationLock.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── background.png │ │ ├── bootstrap.min.css │ │ └── exampleJsInterop.js │ └── Snippets │ └── builder.snippet ├── Chapter13 └── MyBlog │ ├── BlazorWebApp │ ├── BlazorWebApp.Client │ │ ├── BlazorWebApp.Client.csproj │ │ ├── BlogApiWebClient.cs │ │ ├── Pages │ │ │ ├── Admin │ │ │ │ └── TagList.razor │ │ │ └── Counter.razor │ │ ├── PersistentAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── Services │ │ │ ├── BlazorWebAssemblyBlogNotificationService.cs │ │ │ └── BlogBrowserStorage.cs │ │ ├── UserInfo.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ ├── BlazorWebApp.sln │ └── BlazorWebApp │ │ ├── BlazorWebApp.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── CounterWithParameterAndEvent.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── LoginStatus.razor │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Weather.razor │ │ ├── ParentCounter.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Endpoints │ │ ├── BlogPostEndpoints.cs │ │ ├── CategoryEndpoints.cs │ │ ├── CommentEndpoints.cs │ │ └── TagEndpoints.cs │ │ ├── Hubs │ │ └── BlogNotificationHub.cs │ │ ├── PersistingServerAuthenticationStateProvider.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Services │ │ ├── BlazorServerBlogNotificationService.cs │ │ └── BlogProtectedBrowserStorage.cs │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ ├── BlazorWebAssemblyApp │ ├── App.razor │ ├── BlazorWebAssemblyApp.csproj │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── Pages │ │ ├── Counter.razor │ │ ├── Home.razor │ │ ├── ThrowException.razor │ │ └── Weather.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ └── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── favicon.png │ │ ├── icon-192.png │ │ ├── index.html │ │ └── sample-data │ │ └── weather.json │ ├── Data.Models │ ├── BlogPost.cs │ ├── Category.cs │ ├── Comment.cs │ ├── Data.Models.csproj │ ├── Interfaces │ │ └── IBlogApi.cs │ └── Tag.cs │ ├── Data.Tests │ ├── BlogApiTests.cs │ ├── Data.Tests.csproj │ ├── Data │ │ ├── Blogposts │ │ │ ├── 311e92e9-36e4-45dc-8822-1935deb0231e.json │ │ │ └── 9618318e-9df8-41f9-8148-27d677e269cc.json │ │ ├── Categories │ │ │ ├── bebb96a0-3110-4f46-a59d-b99bc3b531e6.json │ │ │ ├── edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json │ │ │ └── fc5fa554-4333-4bae-846a-36e0a975d321.json │ │ ├── Comments │ │ │ ├── db97df73-65ce-4921-acdd-35e3f08752ab.json │ │ │ └── fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json │ │ └── Tags │ │ │ ├── 0b6df322-5dee-4901-90a1-bf07e4e0de01.json │ │ │ ├── d568c4ab-2130-4caf-a653-95176c909c07.json │ │ │ └── fa29eec2-495a-4441-8968-5e9d6310688f.json │ ├── DataTestFixture.cs │ └── GlobalUsings.cs │ ├── Data │ ├── BlogApiJsonDirectAccess.cs │ ├── BlogApiJsonDirectAccessSetting.cs │ └── Data.csproj │ ├── Examples │ ├── CounterWithoutRazor.cs │ ├── WeatherWithCodeBehind.razor │ ├── WeatherWithCodeBehind.razor.cs │ ├── WeatherWithInherits.razor │ └── WeatherWithInheritsModel.cs │ ├── MyBlog.Tests │ ├── BlogApiMock.cs │ ├── MyBlog.Tests.csproj │ ├── Pages │ │ ├── AlertTest.razor │ │ ├── BlogButtonTests.razor │ │ ├── HomeTest.razor │ │ └── LoginStatusTest.razor │ └── _Imports.razor │ ├── MyBlog.sln │ ├── SharedComponents │ ├── BootstrapFieldCssClassProvider.cs │ ├── CustomCssClassProvider.cs │ ├── Demo │ │ ├── HighChart.razor │ │ ├── HighChart.razor.js │ │ ├── HighChartTest.razor │ │ ├── JSInteropSamples │ │ │ ├── JSToReferenceNET.razor │ │ │ ├── JSToReferenceNET.razor.js │ │ │ ├── JSToStaticNET.razor │ │ │ ├── JSToStaticNET.razor.js │ │ │ ├── NetToJS.razor │ │ │ └── NetToJS.razor.js │ │ └── JSInteropSamplesWasm │ │ │ ├── JSToStaticNET.razor │ │ │ ├── JSToStaticNET.razor.cs │ │ │ ├── JSToStaticNET.razor.js │ │ │ ├── NetToJS.razor │ │ │ ├── NetToJS.razor.cs │ │ │ └── NetToJS.razor.js │ ├── ErrorBoundaryDemo │ │ ├── ComponentWithError.razor │ │ ├── CustomErrorBoundaryDemo.razor │ │ └── ErrorBoundaryDemo.razor │ ├── InputTextAreaOnInput.cs │ ├── Interfaces │ │ ├── IBlogNotificationService.cs │ │ └── IBrowserStorage.cs │ ├── ItemList.razor │ ├── Nuget.config │ ├── Pages │ │ ├── Admin │ │ │ ├── BlogPostEdit.razor │ │ │ ├── BlogPostList.razor │ │ │ └── CategoryList.razor │ │ ├── AlertTest.razor │ │ ├── Comments.razor │ │ ├── ErrorBoundaryTest.razor │ │ ├── Home.razor │ │ ├── Post.razor │ │ ├── RenderFragmentTest.razor │ │ ├── SetFocus.razor │ │ └── ThrowException.razor │ ├── ReusableComponents │ │ ├── Alert.razor │ │ ├── BlogButton.razor │ │ ├── BlogButton.razor.js │ │ ├── BlogInputText.razor │ │ └── BlogNavigationLock.razor │ ├── SharedComponents.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── background.png │ │ ├── bootstrap.min.css │ │ └── exampleJsInterop.js │ └── Snippets │ └── builder.snippet ├── Chapter15 └── CustomElements │ ├── AngularProject │ ├── AngularProject.Server │ │ ├── AngularProject.Server.csproj │ │ ├── AngularProject.Server.http │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── angularproject.client │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── .vscode │ │ ├── extensions.json │ │ ├── launch.json │ │ └── tasks.json │ │ ├── README.md │ │ ├── angular.json │ │ ├── angularproject.client.esproj │ │ ├── aspnetcore-https.js │ │ ├── karma.conf.js │ │ ├── nuget.config │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── app │ │ │ ├── app-routing.module.ts │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── app.component.spec.ts │ │ │ ├── app.component.ts │ │ │ └── app.module.ts │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── proxy.conf.js │ │ └── styles.css │ │ ├── tsconfig.app.json │ │ ├── tsconfig.json │ │ └── tsconfig.spec.json │ ├── BlazorCustomElements │ ├── BlazorCustomElements.csproj │ ├── Counter.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ └── _Imports.razor │ ├── BlazorProject │ ├── BlazorProject.Client │ │ ├── BlazorProject.Client.csproj │ │ ├── Pages │ │ │ ├── Counter.razor │ │ │ └── MarkdownDemo.razor │ │ ├── Program.cs │ │ ├── _Imports.razor │ │ ├── package-lock.json │ │ ├── package.json │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ └── BlazorProject │ │ ├── BlazorProject.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ ├── Home.razor │ │ │ └── Weather.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ ├── favicon.png │ │ └── markdown-toolbar-element │ │ ├── LICENSE │ │ ├── README.md │ │ ├── dist │ │ ├── index.d.ts │ │ └── index.js │ │ └── package.json │ ├── CustomElements.sln │ ├── RazorPagesProject │ ├── Pages │ │ ├── Error.cshtml │ │ ├── Error.cshtml.cs │ │ ├── Index.cshtml │ │ ├── Index.cshtml.cs │ │ ├── Privacy.cshtml │ │ ├── Privacy.cshtml.cs │ │ ├── Shared │ │ │ ├── _Layout.cshtml │ │ │ ├── _Layout.cshtml.css │ │ │ └── _ValidationScriptsPartial.cshtml │ │ ├── _ViewImports.cshtml │ │ └── _ViewStart.cshtml │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── RazorPagesProject.csproj │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot │ │ ├── css │ │ └── site.css │ │ ├── favicon.ico │ │ ├── js │ │ └── site.js │ │ └── lib │ │ ├── bootstrap │ │ ├── LICENSE │ │ └── dist │ │ │ ├── css │ │ │ ├── bootstrap-grid.css │ │ │ ├── bootstrap-grid.css.map │ │ │ ├── bootstrap-grid.min.css │ │ │ ├── bootstrap-grid.min.css.map │ │ │ ├── bootstrap-grid.rtl.css │ │ │ ├── bootstrap-grid.rtl.css.map │ │ │ ├── bootstrap-grid.rtl.min.css │ │ │ ├── bootstrap-grid.rtl.min.css.map │ │ │ ├── bootstrap-reboot.css │ │ │ ├── bootstrap-reboot.css.map │ │ │ ├── bootstrap-reboot.min.css │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ ├── bootstrap-reboot.rtl.css │ │ │ ├── bootstrap-reboot.rtl.css.map │ │ │ ├── bootstrap-reboot.rtl.min.css │ │ │ ├── bootstrap-reboot.rtl.min.css.map │ │ │ ├── bootstrap-utilities.css │ │ │ ├── bootstrap-utilities.css.map │ │ │ ├── bootstrap-utilities.min.css │ │ │ ├── bootstrap-utilities.min.css.map │ │ │ ├── bootstrap-utilities.rtl.css │ │ │ ├── bootstrap-utilities.rtl.css.map │ │ │ ├── bootstrap-utilities.rtl.min.css │ │ │ ├── bootstrap-utilities.rtl.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ ├── bootstrap.min.css.map │ │ │ ├── bootstrap.rtl.css │ │ │ ├── bootstrap.rtl.css.map │ │ │ ├── bootstrap.rtl.min.css │ │ │ └── bootstrap.rtl.min.css.map │ │ │ └── js │ │ │ ├── bootstrap.bundle.js │ │ │ ├── bootstrap.bundle.js.map │ │ │ ├── bootstrap.bundle.min.js │ │ │ ├── bootstrap.bundle.min.js.map │ │ │ ├── bootstrap.esm.js │ │ │ ├── bootstrap.esm.js.map │ │ │ ├── bootstrap.esm.min.js │ │ │ ├── bootstrap.esm.min.js.map │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.js.map │ │ │ ├── bootstrap.min.js │ │ │ └── bootstrap.min.js.map │ │ ├── jquery-validation-unobtrusive │ │ ├── LICENSE.txt │ │ ├── jquery.validate.unobtrusive.js │ │ └── jquery.validate.unobtrusive.min.js │ │ ├── jquery-validation │ │ ├── LICENSE.md │ │ └── dist │ │ │ ├── additional-methods.js │ │ │ ├── additional-methods.min.js │ │ │ ├── jquery.validate.js │ │ │ └── jquery.validate.min.js │ │ └── jquery │ │ ├── LICENSE.txt │ │ └── dist │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map │ └── ReactProject │ ├── ReactProject.Server │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── ReactProject.Server.csproj │ ├── ReactProject.Server.http │ ├── appsettings.Development.json │ └── appsettings.json │ └── reactproject.client │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── README.md │ ├── index.html │ ├── nuget.config │ ├── package-lock.json │ ├── package.json │ ├── public │ └── vite.svg │ ├── reactproject.client.esproj │ ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── index.css │ ├── main.tsx │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── Chapter16 ├── BlazorPrerender │ ├── BlazorPrerender.Client │ │ ├── BlazorPrerender.Client.csproj │ │ ├── Pages │ │ │ ├── Counter.razor │ │ │ └── Weather.razor │ │ ├── Program.cs │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── appsettings.Development.json │ │ │ └── appsettings.json │ └── BlazorPrerender │ │ ├── BlazorPrerender.csproj │ │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Error.razor │ │ │ └── Home.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png └── BlazorWebAssembly │ ├── BlazorWebAssembly.sln │ ├── BlazorWebAssembly │ ├── App.razor │ ├── BlazorWebAssembly.csproj │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── Pages │ │ ├── Counter.razor │ │ ├── Home.razor │ │ └── Weather.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ └── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── favicon.png │ │ ├── icon-192.png │ │ ├── index.html │ │ └── sample-data │ │ └── weather.json │ ├── RunningCode │ ├── App.razor │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── Pages │ │ ├── Counter.razor │ │ ├── Home.razor │ │ └── Weather.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── RunningCode.csproj │ ├── Test.c │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ └── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── favicon.png │ │ ├── icon-192.png │ │ ├── index.html │ │ └── sample-data │ │ └── weather.json │ └── SkiaSharpDemo │ ├── App.razor │ ├── Layout │ ├── MainLayout.razor │ ├── MainLayout.razor.css │ ├── NavMenu.razor │ └── NavMenu.razor.css │ ├── Pages │ ├── Counter.razor │ ├── Home.razor │ └── Weather.razor │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── SkiaSharpDemo.csproj │ ├── _Imports.razor │ └── wwwroot │ ├── css │ ├── app.css │ └── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── favicon.png │ ├── icon-192.png │ ├── index.html │ └── sample-data │ └── weather.json ├── Chapter17 └── SourceGeneratorDemo │ ├── BlazorWebAssembly │ ├── App.razor │ ├── BlazorWebAssembly.csproj │ ├── InterfaceGeneratorDemo │ │ └── SampleService.cs │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── Pages │ │ ├── Counter.razor │ │ ├── Home.razor │ │ └── Weather.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ └── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── favicon.png │ │ ├── icon-192.png │ │ ├── index.html │ │ └── sample-data │ │ └── weather.json │ ├── BlazorWebAssemblyApp │ ├── App.razor │ ├── BlazorWebAssemblyApp.csproj │ ├── InterfaceGeneratorDemo │ │ └── SampleService.cs │ ├── Pages │ │ ├── Counter.razor │ │ ├── FetchData.razor │ │ └── Index.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Shared │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ ├── NavMenu.razor.css │ │ └── SurveyPrompt.razor │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ ├── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ └── open-iconic │ │ │ ├── FONT-LICENSE │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ │ ├── favicon.png │ │ ├── icon-192.png │ │ ├── index.html │ │ └── sample-data │ │ └── weather.json │ ├── SourceGenerator │ ├── HelloSourceGenerator.cs │ └── SourceGenerator.csproj │ └── SourceGeneratorDemo.sln ├── Chapter18 └── BlazorHybridApp │ ├── BlazorHybridApp.sln │ └── BlazorHybridApp │ ├── App.xaml │ ├── App.xaml.cs │ ├── BlazorHybridApp.csproj │ ├── Components │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ └── Pages │ │ ├── Counter.razor │ │ ├── Home.razor │ │ └── Weather.razor │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── MauiProgram.cs │ ├── Platforms │ ├── Android │ │ ├── AndroidManifest.xml │ │ ├── MainActivity.cs │ │ ├── MainApplication.cs │ │ └── Resources │ │ │ └── values │ │ │ └── colors.xml │ ├── MacCatalyst │ │ ├── AppDelegate.cs │ │ ├── Entitlements.plist │ │ ├── Info.plist │ │ └── Program.cs │ ├── Tizen │ │ ├── Main.cs │ │ └── tizen-manifest.xml │ ├── Windows │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── Package.appxmanifest │ │ └── app.manifest │ └── iOS │ │ ├── AppDelegate.cs │ │ ├── Info.plist │ │ └── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Resources │ ├── AppIcon │ │ ├── appicon.svg │ │ └── appiconfg.svg │ ├── Fonts │ │ └── OpenSans-Regular.ttf │ ├── Images │ │ └── dotnet_bot.svg │ ├── Raw │ │ └── AboutAssets.txt │ └── Splash │ │ └── splash.svg │ ├── Routes.razor │ ├── _Imports.razor │ └── wwwroot │ ├── css │ ├── app.css │ └── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── favicon.png │ └── index.html ├── Data ├── Blogposts │ ├── BellaGreenHaven.json │ ├── BellaGreenHaven_Story.json │ ├── EllieRainbowBrush_Story.json │ ├── JasperCityLightsAdventure_Story.json │ ├── OliverStarryQuest_Story.json │ ├── RickyTheRaccoon_Story.json │ ├── RockyTheHeroRaccoon_Story.json │ ├── RoxieTheMusicalRaccoon_Story.json │ └── WhiskersSecretGarden_Story.json ├── Categories │ ├── Category1.json │ └── f23ad71a-6b8c-4f25-9e0f-667211bf29df.json ├── Comments │ ├── 22ecaf2f-e056-4930-adb6-c2821ba3d54d.json │ ├── 30102fc1-6181-48d8-ac74-14ad0408c5f7.json │ ├── 5233b24f-0d62-4353-b956-43cde805d478.json │ ├── 719c89e1-106d-48f2-a9ed-6cc77ccd29d3.json │ ├── 84f95c0c-0d3b-432f-b528-4b183a52f4fc.json │ ├── 97c702a2-5a73-4ba5-ab9f-e8ec5c7bc891.json │ └── ea40b9e5-0db4-46dd-89f6-94759dc169a4.json └── Tags │ ├── f19cd19f-d0f7-4198-9a6e-98028b98104c.json │ └── f96aafe5-8369-4fc9-b169-70b93d962cc8.json ├── ExampleData ├── Blogposts │ ├── BellaGreenHaven_Story.json │ ├── EllieRainbowBrush_Story.json │ ├── JasperCityLightsAdventure_Story.json │ ├── OliverStarryQuest_Story.json │ ├── RickyTheRaccoon_Story.json │ ├── RockyTheHeroRaccoon_Story.json │ ├── RoxieTheMusicalRaccoon_Story.json │ └── WhiskersSecretGarden_Story.json ├── Categories │ └── Category1.json ├── Images │ ├── BellaGreenHaven_Story.webp │ ├── EllieRainbowBrush_Story.webp │ ├── JasperCityLightsAdventure_Story.webp │ ├── OliverStarryQuest_Story.webp │ ├── RickyTheRaccoon_Story.webp │ ├── RockyTheHeroRaccoon_Story.webp │ ├── RoxieTheMusicalRaccoon_Story.webp │ └── WhiskersSecretGarden_Story.webp └── Tags │ └── Tag1.json ├── LICENSE └── README.md /Chapter02/MyBlog/BlazorWebApp/BlazorWebApp.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | 3 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 4 | 5 | await builder.Build().RunAsync(); 6 | -------------------------------------------------------------------------------- /Chapter02/MyBlog/BlazorWebApp/BlazorWebApp.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using BlazorWebApp.Client 10 | -------------------------------------------------------------------------------- /Chapter02/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter02/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter02/MyBlog/BlazorWebApp/BlazorWebApp/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /Chapter02/MyBlog/BlazorWebApp/BlazorWebApp/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter02/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter02/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter02/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter02/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter03/MyBlog/BlazorWebApp/BlazorWebApp.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | 3 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 4 | 5 | await builder.Build().RunAsync(); 6 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/BlazorWebApp/BlazorWebApp.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using BlazorWebApp.Client 10 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/BlazorWebApp/BlazorWebApp/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/BlazorWebApp/BlazorWebApp/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter03/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Models/BlogPost.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | public class BlogPost 3 | { 4 | public string? Id { get; set; } 5 | public string Title { get; set; } = string.Empty; 6 | public string Text { get; set; } = string.Empty; 7 | public DateTime PublishDate { get; set; } 8 | public Category? Category { get; set; } 9 | public List Tags { get; set; } = new(); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | 3 | public class Category 4 | { 5 | public string? Id { get; set; } 6 | public string Name { get; set; } = string.Empty; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Models/Comment.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | 3 | public class Comment 4 | { 5 | public string? Id { get; set; } 6 | public required string BlogPostId { get; set; } 7 | public DateTime Date { get; set; } 8 | public string Text { get; set; } = string.Empty; 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | 3 | public class Tag 4 | { 5 | public string? Id { get; set; } 6 | public string Name { get; set; } = string.Empty; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter03/MyBlog/Data/BlogApiJsonDirectAccessSetting.cs: -------------------------------------------------------------------------------- 1 | namespace Data; 2 | public class BlogApiJsonDirectAccessSetting 3 | { 4 | public string BlogPostsFolder { get; set; } = string.Empty; 5 | public string CategoriesFolder { get; set; } = string.Empty; 6 | public string TagsFolder { get; set; } = string.Empty; 7 | public string CommentsFolder { get; set; } = string.Empty; 8 | public string DataPath { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter03/MyBlog/EntityFramework/Data/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter03/MyBlog/RavenDb/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter04/MyBlog/BlazorWebApp/BlazorWebApp.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | 3 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 4 | 5 | await builder.Build().RunAsync(); 6 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/BlazorWebApp/BlazorWebApp.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using BlazorWebApp.Client 10 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/BlazorWebApp/BlazorWebApp/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/BlazorWebApp/BlazorWebApp/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using BlazorWebApp.Components 10 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter04/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Models/BlogPost.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | public class BlogPost 3 | { 4 | public string? Id { get; set; } 5 | public string Title { get; set; } = string.Empty; 6 | public string Text { get; set; } = string.Empty; 7 | public DateTime PublishDate { get; set; } 8 | public Category? Category { get; set; } 9 | public List Tags { get; set; } = new(); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | 3 | public class Category 4 | { 5 | public string? Id { get; set; } 6 | public string Name { get; set; } = string.Empty; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Models/Comment.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | 3 | public class Comment 4 | { 5 | public string? Id { get; set; } 6 | public required string BlogPostId { get; set; } 7 | public DateTime Date { get; set; } 8 | public string Text { get; set; } = string.Empty; 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | 3 | public class Tag 4 | { 5 | public string? Id { get; set; } 6 | public string Name { get; set; } = string.Empty; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter04/MyBlog/Data/BlogApiJsonDirectAccessSetting.cs: -------------------------------------------------------------------------------- 1 | namespace Data; 2 | public class BlogApiJsonDirectAccessSetting 3 | { 4 | public string BlogPostsFolder { get; set; } = string.Empty; 5 | public string CategoriesFolder { get; set; } = string.Empty; 6 | public string TagsFolder { get; set; } = string.Empty; 7 | public string CommentsFolder { get; set; } = string.Empty; 8 | public string DataPath { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/SharedComponents/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | 10 | -------------------------------------------------------------------------------- /Chapter04/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter04/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter04/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/BlazorWebApp/BlazorWebApp.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | 3 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 4 | 5 | await builder.Build().RunAsync(); 6 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/BlazorWebApp/BlazorWebApp.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using BlazorWebApp.Client 10 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/BlazorWebApp/BlazorWebApp/Components/ParentCounter.razor: -------------------------------------------------------------------------------- 1 | @page "/parentcounter" 2 | 3 | The current count is: @currentcount 4 | @code { 5 | int incrementamount = 10; 6 | int currentcount = 0; 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/BlazorWebApp/BlazorWebApp/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter05/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Models/BlogPost.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | public class BlogPost 3 | { 4 | public string? Id { get; set; } 5 | public string Title { get; set; } = string.Empty; 6 | public string Text { get; set; } = string.Empty; 7 | public DateTime PublishDate { get; set; } 8 | public Category? Category { get; set; } 9 | public List Tags { get; set; } = new(); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | 3 | public class Category 4 | { 5 | public string? Id { get; set; } 6 | public string Name { get; set; } = string.Empty; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Models/Comment.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | 3 | public class Comment 4 | { 5 | public string? Id { get; set; } 6 | public required string BlogPostId { get; set; } 7 | public DateTime Date { get; set; } 8 | public string Text { get; set; } = string.Empty; 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | namespace Data.Models; 2 | 3 | public class Tag 4 | { 5 | public string? Id { get; set; } 6 | public string Name { get; set; } = string.Empty; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter05/MyBlog/Data/BlogApiJsonDirectAccessSetting.cs: -------------------------------------------------------------------------------- 1 | namespace Data; 2 | public class BlogApiJsonDirectAccessSetting 3 | { 4 | public string BlogPostsFolder { get; set; } = string.Empty; 5 | public string CategoriesFolder { get; set; } = string.Empty; 6 | public string TagsFolder { get; set; } = string.Empty; 7 | public string CommentsFolder { get; set; } = string.Empty; 8 | public string DataPath { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/ErrorBoundaryDemo/ComponentWithError.razor: -------------------------------------------------------------------------------- 1 | 

ComponentWithError

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/ErrorBoundaryDemo/CustomErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/customerrorboundary" 2 | 3 | 4 | 5 | 6 | 7 |

Oops... something broke

8 |
9 |
-------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/ErrorBoundaryDemo/ErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundary" 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/Pages/AlertTest.razor: -------------------------------------------------------------------------------- 1 | @page "/alerttest" 2 | @using SharedComponents.ReusableComponents 3 | 4 | This is a test 5 | 6 | 7 | 8 | This is another test 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/Pages/ErrorBoundaryTest.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundarytest" 2 | 3 | 4 |

@(1/zero)

5 |
6 | 7 | An error occured 8 | @ex.Message 9 | 10 |
11 | @code { 12 | int zero = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/Pages/RenderFragmentTest.razor: -------------------------------------------------------------------------------- 1 | @page "/RenderFragmentTest" 2 | 3 | @for (int i = 0; i < 10; i++) 4 | { 5 | @Render(i) 6 | } 7 | 8 | @code 9 | { 10 | private RenderFragment Render(int number) 11 | { 12 | return @

This is a render fragment @number

; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/Pages/SetFocus.razor: -------------------------------------------------------------------------------- 1 | @page "/setfocus" 2 | 3 | 4 | 5 | 6 | @code { 7 | ElementReference textInput; 8 | } -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using Microsoft.AspNetCore.Components.Sections 10 | -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter05/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter05/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/BlazorWebApp/BlazorWebApp.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | 3 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 4 | await builder.Build().RunAsync(); 5 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/BlazorWebApp/BlazorWebApp.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using BlazorWebApp.Client 10 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/BlazorWebApp/BlazorWebApp/Components/ParentCounter.razor: -------------------------------------------------------------------------------- 1 | @page "/parentcounter" 2 | 3 | The current count is: @currentcount 4 | @code { 5 | int incrementamount = 10; 6 | int currentcount = 0; 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/BlazorWebApp/BlazorWebApp/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter06/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Category 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Tag 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter06/MyBlog/Data/BlogApiJsonDirectAccessSetting.cs: -------------------------------------------------------------------------------- 1 | namespace Data; 2 | public class BlogApiJsonDirectAccessSetting 3 | { 4 | public string BlogPostsFolder { get; set; } = string.Empty; 5 | public string CategoriesFolder { get; set; } = string.Empty; 6 | public string TagsFolder { get; set; } = string.Empty; 7 | public string CommentsFolder { get; set; } = string.Empty; 8 | public string DataPath { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/ErrorBoundaryDemo/ComponentWithError.razor: -------------------------------------------------------------------------------- 1 | 

ComponentWithError

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/ErrorBoundaryDemo/CustomErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/customerrorboundary" 2 | 3 | 4 | 5 | 6 | 7 |

Oops... something broke

8 |
9 |
-------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/ErrorBoundaryDemo/ErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundary" 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/Pages/AlertTest.razor: -------------------------------------------------------------------------------- 1 | @page "/alerttest" 2 | @using SharedComponents.ReusableComponents 3 | 4 | This is a test 5 | 6 | 7 | 8 | This is another test 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/Pages/ErrorBoundaryTest.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundarytest" 2 | 3 | 4 |

@(1/zero)

5 |
6 | 7 | An error occured 8 | @ex.Message 9 | 10 |
11 | @code { 12 | int zero = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/Pages/RenderFragmentTest.razor: -------------------------------------------------------------------------------- 1 | @page "/RenderFragmentTest" 2 | 3 | @for (int i = 0; i < 10; i++) 4 | { 5 | @Render(i) 6 | } 7 | 8 | @code 9 | { 10 | private RenderFragment Render(int number) 11 | { 12 | return @

This is a render fragment @number

; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/Pages/SetFocus.razor: -------------------------------------------------------------------------------- 1 | @page "/setfocus" 2 | 3 | 4 | 5 | 6 | @code { 7 | ElementReference textInput; 8 | } -------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter06/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter06/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/BlazorWebApp/BlazorWebApp.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | 3 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 4 | await builder.Build().RunAsync(); 5 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/BlazorWebApp/BlazorWebApp.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using BlazorWebApp.Client 10 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/BlazorWebApp/BlazorWebApp/Components/ParentCounter.razor: -------------------------------------------------------------------------------- 1 | @page "/parentcounter" 2 | 3 | The current count is: @currentcount 4 | @code { 5 | int incrementamount = 10; 6 | int currentcount = 0; 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/BlazorWebApp/BlazorWebApp/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter07/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Category 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Tag 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter07/MyBlog/Data/BlogApiJsonDirectAccessSetting.cs: -------------------------------------------------------------------------------- 1 | namespace Data; 2 | public class BlogApiJsonDirectAccessSetting 3 | { 4 | public string BlogPostsFolder { get; set; } = string.Empty; 5 | public string CategoriesFolder { get; set; } = string.Empty; 6 | public string TagsFolder { get; set; } = string.Empty; 7 | public string CommentsFolder { get; set; } = string.Empty; 8 | public string DataPath { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/ErrorBoundaryDemo/ComponentWithError.razor: -------------------------------------------------------------------------------- 1 | 

ComponentWithError

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/ErrorBoundaryDemo/CustomErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/customerrorboundary" 2 | 3 | 4 | 5 | 6 | 7 |

Oops... something broke

8 |
9 |
-------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/ErrorBoundaryDemo/ErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundary" 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/Pages/AlertTest.razor: -------------------------------------------------------------------------------- 1 | @page "/alerttest" 2 | @using SharedComponents.ReusableComponents 3 | 4 | This is a test 5 | 6 | 7 | 8 | This is another test 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/Pages/ErrorBoundaryTest.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundarytest" 2 | 3 | 4 |

@(1/zero)

5 |
6 | 7 | An error occured 8 | @ex.Message 9 | 10 |
11 | @code { 12 | int zero = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/Pages/RenderFragmentTest.razor: -------------------------------------------------------------------------------- 1 | @page "/RenderFragmentTest" 2 | 3 | @for (int i = 0; i < 10; i++) 4 | { 5 | @Render(i) 6 | } 7 | 8 | @code 9 | { 10 | private RenderFragment Render(int number) 11 | { 12 | return @

This is a render fragment @number

; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/Pages/SetFocus.razor: -------------------------------------------------------------------------------- 1 | @page "/setfocus" 2 | 3 | 4 | 5 | 6 | @code { 7 | ElementReference textInput; 8 | } -------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter07/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter07/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/BlazorWebApp/BlazorWebApp/Components/LoginStatus.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | Log out 4 | 5 | 6 | Log in 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/BlazorWebApp/BlazorWebApp/Components/ParentCounter.razor: -------------------------------------------------------------------------------- 1 | @page "/parentcounter" 2 | 3 | The current count is: @currentcount 4 | @code { 5 | int incrementamount = 10; 6 | int currentcount = 0; 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "Auth0": { 10 | "Authority": "Get this from the domain for your application at Auth0", 11 | "ClientId": "Get this from Auth0 setting" 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter08/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Category 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Tag 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter08/MyBlog/Data/BlogApiJsonDirectAccessSetting.cs: -------------------------------------------------------------------------------- 1 | namespace Data; 2 | public class BlogApiJsonDirectAccessSetting 3 | { 4 | public string BlogPostsFolder { get; set; } = string.Empty; 5 | public string CategoriesFolder { get; set; } = string.Empty; 6 | public string TagsFolder { get; set; } = string.Empty; 7 | public string CommentsFolder { get; set; } = string.Empty; 8 | public string DataPath { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/ErrorBoundaryDemo/ComponentWithError.razor: -------------------------------------------------------------------------------- 1 | 

ComponentWithError

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/ErrorBoundaryDemo/CustomErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/customerrorboundary" 2 | 3 | 4 | 5 | 6 | 7 |

Oops... something broke

8 |
9 |
-------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/ErrorBoundaryDemo/ErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundary" 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/Pages/AlertTest.razor: -------------------------------------------------------------------------------- 1 | @page "/alerttest" 2 | @using SharedComponents.ReusableComponents 3 | 4 | This is a test 5 | 6 | 7 | 8 | This is another test 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/Pages/ErrorBoundaryTest.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundarytest" 2 | 3 | 4 |

@(1/zero)

5 |
6 | 7 | An error occured 8 | @ex.Message 9 | 10 |
11 | @code { 12 | int zero = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/Pages/RenderFragmentTest.razor: -------------------------------------------------------------------------------- 1 | @page "/RenderFragmentTest" 2 | 3 | @for (int i = 0; i < 10; i++) 4 | { 5 | @Render(i) 6 | } 7 | 8 | @code 9 | { 10 | private RenderFragment Render(int number) 11 | { 12 | return @

This is a render fragment @number

; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/Pages/SetFocus.razor: -------------------------------------------------------------------------------- 1 | @page "/setfocus" 2 | 3 | 4 | 5 | 6 | @code { 7 | ElementReference textInput; 8 | } -------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter08/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter08/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/BlazorWebApp/BlazorWebApp/Components/LoginStatus.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | Log out 4 | 5 | 6 | Log in 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/BlazorWebApp/BlazorWebApp/Components/ParentCounter.razor: -------------------------------------------------------------------------------- 1 | @page "/parentcounter" 2 | 3 | The current count is: @currentcount 4 | @code { 5 | int incrementamount = 10; 6 | int currentcount = 0; 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "Auth0": { 10 | "Authority": "Get this from the domain for your application at Auth0", 11 | "ClientId": "Get this from Auth0 setting" 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter09/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Category 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Tag 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter09/MyBlog/Data/BlogApiJsonDirectAccessSetting.cs: -------------------------------------------------------------------------------- 1 | namespace Data; 2 | public class BlogApiJsonDirectAccessSetting 3 | { 4 | public string BlogPostsFolder { get; set; } = string.Empty; 5 | public string CategoriesFolder { get; set; } = string.Empty; 6 | public string TagsFolder { get; set; } = string.Empty; 7 | public string CommentsFolder { get; set; } = string.Empty; 8 | public string DataPath { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/ErrorBoundaryDemo/ComponentWithError.razor: -------------------------------------------------------------------------------- 1 | 

ComponentWithError

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/ErrorBoundaryDemo/CustomErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/customerrorboundary" 2 | 3 | 4 | 5 | 6 | 7 |

Oops... something broke

8 |
9 |
-------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/ErrorBoundaryDemo/ErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundary" 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/Pages/AlertTest.razor: -------------------------------------------------------------------------------- 1 | @page "/alerttest" 2 | @using SharedComponents.ReusableComponents 3 | 4 | This is a test 5 | 6 | 7 | 8 | This is another test 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/Pages/ErrorBoundaryTest.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundarytest" 2 | 3 | 4 |

@(1/zero)

5 |
6 | 7 | An error occured 8 | @ex.Message 9 | 10 |
11 | @code { 12 | int zero = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/Pages/RenderFragmentTest.razor: -------------------------------------------------------------------------------- 1 | @page "/RenderFragmentTest" 2 | 3 | @for (int i = 0; i < 10; i++) 4 | { 5 | @Render(i) 6 | } 7 | 8 | @code 9 | { 10 | private RenderFragment Render(int number) 11 | { 12 | return @

This is a render fragment @number

; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/Pages/SetFocus.razor: -------------------------------------------------------------------------------- 1 | @page "/setfocus" 2 | 3 | 4 | 5 | 6 | @code { 7 | ElementReference textInput; 8 | } -------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter09/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter09/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/BlazorWebApp/BlazorWebApp.Client/UserInfo.cs: -------------------------------------------------------------------------------- 1 | namespace BlazorWebApp.Client; 2 | 3 | // Add properties to this class and update the server and client AuthenticationStateProviders 4 | // to expose more information about the authenticated user to the client. 5 | public class UserInfo 6 | { 7 | public required string UserId { get; set; } 8 | public required string Email { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/BlazorWebApp/BlazorWebApp/Components/LoginStatus.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | Log out 4 | 5 | 6 | Log in 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/BlazorWebApp/BlazorWebApp/Components/ParentCounter.razor: -------------------------------------------------------------------------------- 1 | @page "/parentcounter" 2 | 3 | The current count is: @currentcount 4 | @code { 5 | int incrementamount = 10; 6 | int currentcount = 0; 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "DetailedErrors": true, 9 | "AllowedHosts": "*", 10 | "Auth0": { 11 | "Authority": "Get this from the domain for your application at Auth0", 12 | "ClientId": "Get this from Auth0 setting" 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter10/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Category 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Tag 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter10/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Demo/HighChart.razor.js: -------------------------------------------------------------------------------- 1 | export function loadHighchart(id, json) { 2 | var obj = looseJsonParse(json); 3 | Highcharts.chart(id, obj); 4 | }; 5 | 6 | export function looseJsonParse(obj) { 7 | return Function('"use strict";return (' + obj + ')')(); 8 | } -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Demo/JSInteropSamples/JSToReferenceNET.razor.js: -------------------------------------------------------------------------------- 1 | window.callreferencenetfromjs = (dotNetHelper) => { 2 | return dotNetHelper.invokeMethodAsync('GetHelloMessage'); 3 | }; -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Demo/JSInteropSamples/JSToStaticNET.razor.js: -------------------------------------------------------------------------------- 1 |  2 | window.callnetfromjs = () => { 3 | DotNet.invokeMethodAsync('SharedComponents', 'NameOfTheMethod') 4 | .then(data => { 5 | alert(data); 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Demo/JSInteropSamples/NetToJS.razor.js: -------------------------------------------------------------------------------- 1 | export function showAlert(message) { 2 | return alert(message); 3 | } -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Demo/JSInteropSamplesWasm/NetToJS.razor.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices.JavaScript; 2 | namespace SharedComponents.Demo.JSInteropSamplesWasm; 3 | public partial class NetToJS 4 | { 5 | [JSImport("showAlert", "nettojs")] 6 | internal static partial string ShowAlert(string message); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Demo/JSInteropSamplesWasm/NetToJS.razor.js: -------------------------------------------------------------------------------- 1 | export function showAlert(message) { 2 | return alert(message); 3 | } -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/ErrorBoundaryDemo/ComponentWithError.razor: -------------------------------------------------------------------------------- 1 | 

ComponentWithError

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/ErrorBoundaryDemo/CustomErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/customerrorboundary" 2 | 3 | 4 | 5 | 6 | 7 |

Oops... something broke

8 |
9 |
-------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/ErrorBoundaryDemo/ErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundary" 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Pages/AlertTest.razor: -------------------------------------------------------------------------------- 1 | @page "/alerttest" 2 | @using SharedComponents.ReusableComponents 3 | 4 | This is a test 5 | 6 | 7 | 8 | This is another test 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Pages/ErrorBoundaryTest.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundarytest" 2 | 3 | 4 |

@(1/zero)

5 |
6 | 7 | An error occured 8 | @ex.Message 9 | 10 |
11 | @code { 12 | int zero = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Pages/RenderFragmentTest.razor: -------------------------------------------------------------------------------- 1 | @page "/RenderFragmentTest" 2 | 3 | @for (int i = 0; i < 10; i++) 4 | { 5 | @Render(i) 6 | } 7 | 8 | @code 9 | { 10 | private RenderFragment Render(int number) 11 | { 12 | return @

This is a render fragment @number

; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/Pages/SetFocus.razor: -------------------------------------------------------------------------------- 1 | @page "/setfocus" 2 | 3 | 4 | 5 | 6 | @code { 7 | ElementReference textInput; 8 | } -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/ReusableComponents/BlogButton.razor.js: -------------------------------------------------------------------------------- 1 | export function showConfirm(message) { 2 | return confirm(message); 3 | } 4 | -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter10/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter10/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/BlazorWebApp/BlazorWebApp.Client/UserInfo.cs: -------------------------------------------------------------------------------- 1 | namespace BlazorWebApp.Client; 2 | 3 | // Add properties to this class and update the server and client AuthenticationStateProviders 4 | // to expose more information about the authenticated user to the client. 5 | public class UserInfo 6 | { 7 | public required string UserId { get; set; } 8 | public required string Email { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/BlazorWebApp/BlazorWebApp/Components/LoginStatus.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | Log out 4 | 5 | 6 | Log in 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/BlazorWebApp/BlazorWebApp/Components/ParentCounter.razor: -------------------------------------------------------------------------------- 1 | @page "/parentcounter" 2 | 3 | The current count is: @currentcount 4 | @code { 5 | int incrementamount = 10; 6 | int currentcount = 0; 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/BlazorWebApp/BlazorWebApp/Hubs/BlogNotificationHub.cs: -------------------------------------------------------------------------------- 1 | using Data.Models; 2 | using Microsoft.AspNetCore.SignalR; 3 | namespace BlazorWebApp.Hubs; 4 | public class BlogNotificationHub : Hub 5 | { 6 | public async Task SendNotification(BlogPost post) 7 | { 8 | await Clients.All.SendAsync("BlogPostChanged", post); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "DetailedErrors": true, 9 | "AllowedHosts": "*", 10 | "Auth0": { 11 | "Authority": "Get this from the domain for your application at Auth0", 12 | "ClientId": "Get this from Auth0 setting" 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter11/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Category 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Tag 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter11/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter11/MyBlog/RootLevelCascadingValueDemo/RootLevelCascadingValueDemo.Client/CascadingValueDemo.razor: -------------------------------------------------------------------------------- 1 | 

CascadingValueDemo

2 | @(Preferences?.DarkTheme) 3 | 4 | 5 | @code { 6 | 7 | [CascadingParameter(Name = "Preferences")] 8 | public Preferences Preferences { get; set; } 9 | 10 | [Parameter] 11 | public string RenderedAs { get; set; } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/RootLevelCascadingValueDemo/RootLevelCascadingValueDemo.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/RootLevelCascadingValueDemo/RootLevelCascadingValueDemo.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/RootLevelCascadingValueDemo/RootLevelCascadingValueDemo/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/RootLevelCascadingValueDemo/RootLevelCascadingValueDemo/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/RootLevelCascadingValueDemo/RootLevelCascadingValueDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/RootLevelCascadingValueDemo/RootLevelCascadingValueDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/RootLevelCascadingValueDemo/RootLevelCascadingValueDemo/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter11/MyBlog/RootLevelCascadingValueDemo/RootLevelCascadingValueDemo/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Demo/HighChart.razor.js: -------------------------------------------------------------------------------- 1 | export function loadHighchart(id, json) { 2 | var obj = looseJsonParse(json); 3 | Highcharts.chart(id, obj); 4 | }; 5 | 6 | export function looseJsonParse(obj) { 7 | return Function('"use strict";return (' + obj + ')')(); 8 | } -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Demo/JSInteropSamples/JSToReferenceNET.razor.js: -------------------------------------------------------------------------------- 1 | window.callreferencenetfromjs = (dotNetHelper) => { 2 | return dotNetHelper.invokeMethodAsync('GetHelloMessage'); 3 | }; -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Demo/JSInteropSamples/JSToStaticNET.razor.js: -------------------------------------------------------------------------------- 1 |  2 | window.callnetfromjs = () => { 3 | DotNet.invokeMethodAsync('SharedComponents', 'NameOfTheMethod') 4 | .then(data => { 5 | alert(data); 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Demo/JSInteropSamples/NetToJS.razor.js: -------------------------------------------------------------------------------- 1 | export function showAlert(message) { 2 | return alert(message); 3 | } -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Demo/JSInteropSamplesWasm/NetToJS.razor.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices.JavaScript; 2 | namespace SharedComponents.Demo.JSInteropSamplesWasm; 3 | public partial class NetToJS 4 | { 5 | [JSImport("showAlert", "nettojs")] 6 | internal static partial string ShowAlert(string message); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Demo/JSInteropSamplesWasm/NetToJS.razor.js: -------------------------------------------------------------------------------- 1 | export function showAlert(message) { 2 | return alert(message); 3 | } -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/ErrorBoundaryDemo/ComponentWithError.razor: -------------------------------------------------------------------------------- 1 | 

ComponentWithError

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/ErrorBoundaryDemo/CustomErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/customerrorboundary" 2 | 3 | 4 | 5 | 6 | 7 |

Oops... something broke

8 |
9 |
-------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/ErrorBoundaryDemo/ErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundary" 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Interfaces/IBlogNotificationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Data.Models; 8 | namespace SharedComponents.Interfaces; 9 | public interface IBlogNotificationService 10 | { 11 | event Action? BlogPostChanged; 12 | Task SendNotification(BlogPost post); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Interfaces/IBrowserStorage.cs: -------------------------------------------------------------------------------- 1 | namespace SharedComponents.Interfaces; 2 | public interface IBrowserStorage 3 | { 4 | Task GetAsync(string key); 5 | Task SetAsync(string key, object value); 6 | Task DeleteAsync(string key); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Pages/AlertTest.razor: -------------------------------------------------------------------------------- 1 | @page "/alerttest" 2 | @using SharedComponents.ReusableComponents 3 | 4 | This is a test 5 | 6 | 7 | 8 | This is another test 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Pages/ErrorBoundaryTest.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundarytest" 2 | 3 | 4 |

@(1/zero)

5 |
6 | 7 | An error occured 8 | @ex.Message 9 | 10 |
11 | @code { 12 | int zero = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Pages/RenderFragmentTest.razor: -------------------------------------------------------------------------------- 1 | @page "/RenderFragmentTest" 2 | 3 | @for (int i = 0; i < 10; i++) 4 | { 5 | @Render(i) 6 | } 7 | 8 | @code 9 | { 10 | private RenderFragment Render(int number) 11 | { 12 | return @

This is a render fragment @number

; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/Pages/SetFocus.razor: -------------------------------------------------------------------------------- 1 | @page "/setfocus" 2 | 3 | 4 | 5 | 6 | @code { 7 | ElementReference textInput; 8 | } -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/ReusableComponents/BlogButton.razor.js: -------------------------------------------------------------------------------- 1 | export function showConfirm(message) { 2 | return confirm(message); 3 | } 4 | -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter11/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter11/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebApp/BlazorWebApp.Client/UserInfo.cs: -------------------------------------------------------------------------------- 1 | namespace BlazorWebApp.Client; 2 | 3 | // Add properties to this class and update the server and client AuthenticationStateProviders 4 | // to expose more information about the authenticated user to the client. 5 | public class UserInfo 6 | { 7 | public required string UserId { get; set; } 8 | public required string Email { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebApp/BlazorWebApp/Components/LoginStatus.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | Log out 4 | 5 | 6 | Log in 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebApp/BlazorWebApp/Components/ParentCounter.razor: -------------------------------------------------------------------------------- 1 | @page "/parentcounter" 2 | 3 | The current count is: @currentcount 4 | @code { 5 | int incrementamount = 10; 6 | int currentcount = 0; 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebApp/BlazorWebApp/Hubs/BlogNotificationHub.cs: -------------------------------------------------------------------------------- 1 | using Data.Models; 2 | using Microsoft.AspNetCore.SignalR; 3 | namespace BlazorWebApp.Hubs; 4 | public class BlogNotificationHub : Hub 5 | { 6 | public async Task SendNotification(BlogPost post) 7 | { 8 | await Clients.All.SendAsync("BlogPostChanged", post); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "DetailedErrors": true, 9 | "AllowedHosts": "*", 10 | "Auth0": { 11 | "Authority": "Get this from the domain for your application at Auth0", 12 | "ClientId": "Get this from Auth0 setting" 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter12/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebAssemblyApp/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter2

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebAssemblyApp/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebAssemblyApp/Pages/ThrowException.razor: -------------------------------------------------------------------------------- 1 | @page "/ThrowException" 2 | @rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) 3 | 4 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebAssemblyApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter12/MyBlog/BlazorWebAssemblyApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter12/MyBlog/BlazorWebAssemblyApp/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter12/MyBlog/BlazorWebAssemblyApp/wwwroot/icon-192.png -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Category 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Tag 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter12/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Demo/HighChart.razor.js: -------------------------------------------------------------------------------- 1 | export function loadHighchart(id, json) { 2 | var obj = looseJsonParse(json); 3 | Highcharts.chart(id, obj); 4 | }; 5 | 6 | export function looseJsonParse(obj) { 7 | return Function('"use strict";return (' + obj + ')')(); 8 | } -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Demo/JSInteropSamples/JSToReferenceNET.razor.js: -------------------------------------------------------------------------------- 1 | window.callreferencenetfromjs = (dotNetHelper) => { 2 | return dotNetHelper.invokeMethodAsync('GetHelloMessage'); 3 | }; -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Demo/JSInteropSamples/JSToStaticNET.razor.js: -------------------------------------------------------------------------------- 1 |  2 | window.callnetfromjs = () => { 3 | DotNet.invokeMethodAsync('SharedComponents', 'NameOfTheMethod') 4 | .then(data => { 5 | alert(data); 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Demo/JSInteropSamples/NetToJS.razor.js: -------------------------------------------------------------------------------- 1 | export function showAlert(message) { 2 | return alert(message); 3 | } -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Demo/JSInteropSamplesWasm/NetToJS.razor.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices.JavaScript; 2 | namespace SharedComponents.Demo.JSInteropSamplesWasm; 3 | public partial class NetToJS 4 | { 5 | [JSImport("showAlert", "nettojs")] 6 | internal static partial string ShowAlert(string message); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Demo/JSInteropSamplesWasm/NetToJS.razor.js: -------------------------------------------------------------------------------- 1 | export function showAlert(message) { 2 | return alert(message); 3 | } -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/ErrorBoundaryDemo/ComponentWithError.razor: -------------------------------------------------------------------------------- 1 | 

ComponentWithError

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/ErrorBoundaryDemo/CustomErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/customerrorboundary" 2 | 3 | 4 | 5 | 6 | 7 |

Oops... something broke

8 |
9 |
-------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/ErrorBoundaryDemo/ErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundary" 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Interfaces/IBlogNotificationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Data.Models; 8 | namespace SharedComponents.Interfaces; 9 | public interface IBlogNotificationService 10 | { 11 | event Action? BlogPostChanged; 12 | Task SendNotification(BlogPost post); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Interfaces/IBrowserStorage.cs: -------------------------------------------------------------------------------- 1 | namespace SharedComponents.Interfaces; 2 | public interface IBrowserStorage 3 | { 4 | Task GetAsync(string key); 5 | Task SetAsync(string key, object value); 6 | Task DeleteAsync(string key); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Pages/AlertTest.razor: -------------------------------------------------------------------------------- 1 | @page "/alerttest" 2 | @using SharedComponents.ReusableComponents 3 | 4 | This is a test 5 | 6 | 7 | 8 | This is another test 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Pages/ErrorBoundaryTest.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundarytest" 2 | 3 | 4 |

@(1/zero)

5 |
6 | 7 | An error occured 8 | @ex.Message 9 | 10 |
11 | @code { 12 | int zero = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Pages/RenderFragmentTest.razor: -------------------------------------------------------------------------------- 1 | @page "/RenderFragmentTest" 2 | 3 | @for (int i = 0; i < 10; i++) 4 | { 5 | @Render(i) 6 | } 7 | 8 | @code 9 | { 10 | private RenderFragment Render(int number) 11 | { 12 | return @

This is a render fragment @number

; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Pages/SetFocus.razor: -------------------------------------------------------------------------------- 1 | @page "/setfocus" 2 | 3 | 4 | 5 | 6 | @code { 7 | ElementReference textInput; 8 | } -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/Pages/ThrowException.razor: -------------------------------------------------------------------------------- 1 | @page "/ThrowException" 2 | @rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) 3 | 4 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/ReusableComponents/BlogButton.razor.js: -------------------------------------------------------------------------------- 1 | export function showConfirm(message) { 2 | return confirm(message); 3 | } 4 | -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter12/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter12/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebApp/BlazorWebApp.Client/UserInfo.cs: -------------------------------------------------------------------------------- 1 | namespace BlazorWebApp.Client; 2 | 3 | // Add properties to this class and update the server and client AuthenticationStateProviders 4 | // to expose more information about the authenticated user to the client. 5 | public class UserInfo 6 | { 7 | public required string UserId { get; set; } 8 | public required string Email { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebApp/BlazorWebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebApp/BlazorWebApp/Components/LoginStatus.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | Log out 4 | 5 | 6 | Log in 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebApp/BlazorWebApp/Components/ParentCounter.razor: -------------------------------------------------------------------------------- 1 | @page "/parentcounter" 2 | 3 | The current count is: @currentcount 4 | @code { 5 | int incrementamount = 10; 6 | int currentcount = 0; 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebApp/BlazorWebApp/Hubs/BlogNotificationHub.cs: -------------------------------------------------------------------------------- 1 | using Data.Models; 2 | using Microsoft.AspNetCore.SignalR; 3 | namespace BlazorWebApp.Hubs; 4 | public class BlogNotificationHub : Hub 5 | { 6 | public async Task SendNotification(BlogPost post) 7 | { 8 | await Clients.All.SendAsync("BlogPostChanged", post); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebApp/BlazorWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "DetailedErrors": true, 9 | "AllowedHosts": "*", 10 | "Auth0": { 11 | "Authority": "Get this from the domain for your application at Auth0", 12 | "ClientId": "Get this from Auth0 setting" 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter13/MyBlog/BlazorWebApp/BlazorWebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebAssemblyApp/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter2

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebAssemblyApp/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebAssemblyApp/Pages/ThrowException.razor: -------------------------------------------------------------------------------- 1 | @page "/ThrowException" 2 | @rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) 3 | 4 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebAssemblyApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter13/MyBlog/BlazorWebAssemblyApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter13/MyBlog/BlazorWebAssemblyApp/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter13/MyBlog/BlazorWebAssemblyApp/wwwroot/icon-192.png -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Category 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Models/Data.Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Models/Tag.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Data.Models; 4 | 5 | public class Tag 6 | { 7 | public string? Id { get; set; } 8 | [Required] 9 | public string Name { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Blogposts/311e92e9-36e4-45dc-8822-1935deb0231e.json: -------------------------------------------------------------------------------- 1 | {"Id":"311e92e9-36e4-45dc-8822-1935deb0231e","Title":"Title 2023-11-03 17:02:21","Text":"Text","PublishDate":"2023-11-03T17:02:21.8137492+01:00","Category":{"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"},"Tags":[{"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"}]} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Blogposts/9618318e-9df8-41f9-8148-27d677e269cc.json: -------------------------------------------------------------------------------- 1 | {"Id":"9618318e-9df8-41f9-8148-27d677e269cc","Title":"Title 2023-11-03 17:01:11","Text":"Text","PublishDate":"2023-11-03T17:01:11.6560768+01:00","Category":{"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"},"Tags":[{"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"}]} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Categories/bebb96a0-3110-4f46-a59d-b99bc3b531e6.json: -------------------------------------------------------------------------------- 1 | {"Id":"bebb96a0-3110-4f46-a59d-b99bc3b531e6","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Categories/edf7eda7-1f58-4e89-b9d0-18cdf596bd91.json: -------------------------------------------------------------------------------- 1 | {"Id":"edf7eda7-1f58-4e89-b9d0-18cdf596bd91","Name":"Category 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Categories/fc5fa554-4333-4bae-846a-36e0a975d321.json: -------------------------------------------------------------------------------- 1 | {"Id":"fc5fa554-4333-4bae-846a-36e0a975d321","Name":"Category 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Comments/db97df73-65ce-4921-acdd-35e3f08752ab.json: -------------------------------------------------------------------------------- 1 | {"Id":"db97df73-65ce-4921-acdd-35e3f08752ab","BlogPostId":"9618318e-9df8-41f9-8148-27d677e269cc","Date":"2023-11-03T17:01:11.6667937+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Comments/fe5e0efb-77b2-471c-ab64-164bad1cf9e9.json: -------------------------------------------------------------------------------- 1 | {"Id":"fe5e0efb-77b2-471c-ab64-164bad1cf9e9","BlogPostId":"311e92e9-36e4-45dc-8822-1935deb0231e","Date":"2023-11-03T17:02:21.820486+01:00","Text":"Amazing post!","Name":"Jimmy"} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Tags/0b6df322-5dee-4901-90a1-bf07e4e0de01.json: -------------------------------------------------------------------------------- 1 | {"Id":"0b6df322-5dee-4901-90a1-bf07e4e0de01","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Tags/d568c4ab-2130-4caf-a653-95176c909c07.json: -------------------------------------------------------------------------------- 1 | {"Id":"d568c4ab-2130-4caf-a653-95176c909c07","Name":"Tag 2023-11-03 17:02:21"} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/Data/Tags/fa29eec2-495a-4441-8968-5e9d6310688f.json: -------------------------------------------------------------------------------- 1 | {"Id":"fa29eec2-495a-4441-8968-5e9d6310688f","Name":"Tag 2023-11-03 17:01:11"} -------------------------------------------------------------------------------- /Chapter13/MyBlog/Data.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /Chapter13/MyBlog/MyBlog.Tests/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Web 2 | @using Microsoft.JSInterop 3 | @using Microsoft.Extensions.DependencyInjection 4 | @using Bunit 5 | @using Bunit.TestDoubles 6 | @using Xunit 7 | @using SharedComponents.Pages 8 | @using Data.Models.Interfaces 9 | @using SharedComponents.ReusableComponents 10 | 11 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Demo/HighChart.razor.js: -------------------------------------------------------------------------------- 1 | export function loadHighchart(id, json) { 2 | var obj = looseJsonParse(json); 3 | Highcharts.chart(id, obj); 4 | }; 5 | 6 | export function looseJsonParse(obj) { 7 | return Function('"use strict";return (' + obj + ')')(); 8 | } -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Demo/JSInteropSamples/JSToReferenceNET.razor.js: -------------------------------------------------------------------------------- 1 | window.callreferencenetfromjs = (dotNetHelper) => { 2 | return dotNetHelper.invokeMethodAsync('GetHelloMessage'); 3 | }; -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Demo/JSInteropSamples/JSToStaticNET.razor.js: -------------------------------------------------------------------------------- 1 |  2 | window.callnetfromjs = () => { 3 | DotNet.invokeMethodAsync('SharedComponents', 'NameOfTheMethod') 4 | .then(data => { 5 | alert(data); 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Demo/JSInteropSamples/NetToJS.razor.js: -------------------------------------------------------------------------------- 1 | export function showAlert(message) { 2 | return alert(message); 3 | } -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Demo/JSInteropSamplesWasm/NetToJS.razor.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices.JavaScript; 2 | namespace SharedComponents.Demo.JSInteropSamplesWasm; 3 | public partial class NetToJS 4 | { 5 | [JSImport("showAlert", "nettojs")] 6 | internal static partial string ShowAlert(string message); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Demo/JSInteropSamplesWasm/NetToJS.razor.js: -------------------------------------------------------------------------------- 1 | export function showAlert(message) { 2 | return alert(message); 3 | } -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/ErrorBoundaryDemo/ComponentWithError.razor: -------------------------------------------------------------------------------- 1 | 

ComponentWithError

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/ErrorBoundaryDemo/CustomErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/customerrorboundary" 2 | 3 | 4 | 5 | 6 | 7 |

Oops... something broke

8 |
9 |
-------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/ErrorBoundaryDemo/ErrorBoundaryDemo.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundary" 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Interfaces/IBlogNotificationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Data.Models; 8 | namespace SharedComponents.Interfaces; 9 | public interface IBlogNotificationService 10 | { 11 | event Action? BlogPostChanged; 12 | Task SendNotification(BlogPost post); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Interfaces/IBrowserStorage.cs: -------------------------------------------------------------------------------- 1 | namespace SharedComponents.Interfaces; 2 | public interface IBrowserStorage 3 | { 4 | Task GetAsync(string key); 5 | Task SetAsync(string key, object value); 6 | Task DeleteAsync(string key); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Pages/AlertTest.razor: -------------------------------------------------------------------------------- 1 | @page "/alerttest" 2 | @using SharedComponents.ReusableComponents 3 | 4 | This is a test 5 | 6 | 7 | 8 | This is another test 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Pages/ErrorBoundaryTest.razor: -------------------------------------------------------------------------------- 1 | @page "/errorboundarytest" 2 | 3 | 4 |

@(1/zero)

5 |
6 | 7 | An error occured 8 | @ex.Message 9 | 10 |
11 | @code { 12 | int zero = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Pages/RenderFragmentTest.razor: -------------------------------------------------------------------------------- 1 | @page "/RenderFragmentTest" 2 | 3 | @for (int i = 0; i < 10; i++) 4 | { 5 | @Render(i) 6 | } 7 | 8 | @code 9 | { 10 | private RenderFragment Render(int number) 11 | { 12 | return @

This is a render fragment @number

; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Pages/SetFocus.razor: -------------------------------------------------------------------------------- 1 | @page "/setfocus" 2 | 3 | 4 | 5 | 6 | @code { 7 | ElementReference textInput; 8 | } -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/Pages/ThrowException.razor: -------------------------------------------------------------------------------- 1 | @page "/ThrowException" 2 | @rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) 3 | 4 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/ReusableComponents/BlogButton.razor.js: -------------------------------------------------------------------------------- 1 | export function showConfirm(message) { 2 | return confirm(message); 3 | } 4 | -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/wwwroot/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter13/MyBlog/SharedComponents/wwwroot/background.png -------------------------------------------------------------------------------- /Chapter13/MyBlog/SharedComponents/wwwroot/exampleJsInterop.js: -------------------------------------------------------------------------------- 1 | // This is a JavaScript module that is loaded on demand. It can export any number of 2 | // functions, and may import other JavaScript modules if required. 3 | 4 | export function showPrompt(message) { 5 | return prompt(message, 'Type anything here'); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/AngularProject.Server/AngularProject.Server.http: -------------------------------------------------------------------------------- 1 | @AngularProject.Server_HostAddress = http://localhost:5131 2 | 3 | GET {{AngularProject.Server_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/AngularProject.Server/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/AngularProject.Server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 3 | "recommendations": ["angular.ng-template"] 4 | } 5 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | const routes: Routes = []; 5 | 6 | @NgModule({ 7 | imports: [RouterModule.forRoot(routes)], 8 | exports: [RouterModule] 9 | }) 10 | export class AppRoutingModule { } 11 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | :host { 2 | max-width: 1280px; 3 | padding: 2rem; 4 | text-align: center; 5 | } 6 | 7 | tr:nth-child(even) { 8 | background: #F2F2F2; 9 | } 10 | 11 | tr:nth-child(odd) { 12 | background: #FFF; 13 | } 14 | 15 | th, td { 16 | padding-left: 1rem; 17 | padding-right: 1rem; 18 | } 19 | 20 | table { 21 | margin: 0 auto; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter15/CustomElements/AngularProject/angularproject.client/src/assets/.gitkeep -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter15/CustomElements/AngularProject/angularproject.client/src/favicon.ico -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/src/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | 3 | import { AppModule } from './app/app.module'; 4 | 5 | 6 | platformBrowserDynamic().bootstrapModule(AppModule) 7 | .catch(err => console.error(err)); 8 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/AngularProject/angularproject.client/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "include": [ 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorCustomElements/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.Web.Virtualization 7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 8 | @using Microsoft.JSInterop 9 | @using BlazorCustomElements 10 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorProject/BlazorProject.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | 3 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 4 | 5 | await builder.Build().RunAsync(); 6 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorProject/BlazorProject.Client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blazorproject.client", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@github/markdown-toolbar-element": "^2.2.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorProject/BlazorProject.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorProject/BlazorProject.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorProject/BlazorProject/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorProject/BlazorProject/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorProject/BlazorProject/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorProject/BlazorProject/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/BlazorProject/BlazorProject/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter15/CustomElements/BlazorProject/BlazorProject/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/Pages/Index.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model IndexModel 3 | @{ 4 | ViewData["Title"] = "Home page"; 5 | } 6 | 7 |
8 |

Welcome

9 |

Learn about building Web apps with ASP.NET Core.

10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/Pages/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model PrivacyModel 3 | @{ 4 | ViewData["Title"] = "Privacy Policy"; 5 | } 6 |

@ViewData["Title"]

7 | 8 |

Use this page to detail your site's privacy policy.

9 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/Pages/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using RazorPagesProject 2 | @namespace RazorPagesProject.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/Pages/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/RazorPagesProject.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter15/CustomElements/RazorPagesProject/wwwroot/favicon.ico -------------------------------------------------------------------------------- /Chapter15/CustomElements/RazorPagesProject/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/ReactProject/ReactProject.Server/ReactProject.Server.http: -------------------------------------------------------------------------------- 1 | @ReactProject.Server_HostAddress = http://localhost:5147 2 | 3 | GET {{ReactProject.Server_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/ReactProject/ReactProject.Server/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/ReactProject/ReactProject.Server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/ReactProject/reactproject.client/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/ReactProject/reactproject.client/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/ReactProject/reactproject.client/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | tr:nth-child(even) { 9 | background: #F2F2F2; 10 | } 11 | 12 | tr:nth-child(odd) { 13 | background: #FFF; 14 | } 15 | 16 | th, td { 17 | padding-left: 1rem; 18 | padding-right: 1rem; 19 | } -------------------------------------------------------------------------------- /Chapter15/CustomElements/ReactProject/reactproject.client/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/ReactProject/reactproject.client/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /Chapter15/CustomElements/ReactProject/reactproject.client/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /Chapter16/BlazorPrerender/BlazorPrerender.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | 3 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 4 | 5 | await builder.Build().RunAsync(); 6 | -------------------------------------------------------------------------------- /Chapter16/BlazorPrerender/BlazorPrerender.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using BlazorPrerender.Client 10 | -------------------------------------------------------------------------------- /Chapter16/BlazorPrerender/BlazorPrerender.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter16/BlazorPrerender/BlazorPrerender.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter16/BlazorPrerender/BlazorPrerender/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /Chapter16/BlazorPrerender/BlazorPrerender/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter16/BlazorPrerender/BlazorPrerender/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter16/BlazorPrerender/BlazorPrerender/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter16/BlazorPrerender/BlazorPrerender/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter16/BlazorPrerender/BlazorPrerender/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/BlazorWebAssembly/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/BlazorWebAssembly/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/BlazorWebAssembly/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter16/BlazorWebAssembly/BlazorWebAssembly/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/BlazorWebAssembly/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter16/BlazorWebAssembly/BlazorWebAssembly/wwwroot/icon-192.png -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/RunningCode/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/RunningCode/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @using System.Runtime.InteropServices 3 | 4 | Native C 5 | 6 |

Native C Test

7 | 8 |

9 | @@fact(3) result: @fact(3) 10 |

11 | 12 | @code { 13 | [DllImport("Test")] 14 | static extern int fact(int n); 15 | } -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/RunningCode/Test.c: -------------------------------------------------------------------------------- 1 | int fact(int n) 2 | { 3 | if (n == 0) return 1; 4 | return n * fact(n - 1); 5 | } -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/RunningCode/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter16/BlazorWebAssembly/RunningCode/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/RunningCode/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter16/BlazorWebAssembly/RunningCode/wwwroot/icon-192.png -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/SkiaSharpDemo/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/SkiaSharpDemo/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter16/BlazorWebAssembly/SkiaSharpDemo/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter16/BlazorWebAssembly/SkiaSharpDemo/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter16/BlazorWebAssembly/SkiaSharpDemo/wwwroot/icon-192.png -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssembly/InterfaceGeneratorDemo/SampleService.cs: -------------------------------------------------------------------------------- 1 | namespace BlazorWebAssemblyApp.InterfaceGeneratorDemo; 2 | using InterfaceGenerator; 3 | 4 | [GenerateAutoInterface] 5 | public class SampleService: ISampleService 6 | { 7 | public double Multiply(double x, double y) 8 | { 9 | return x * y; 10 | } 11 | 12 | public int NiceNumber => 69; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssembly/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssembly/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @inject GeneratedService service 3 |

@service.GetHello()

4 | 5 | Home 6 | 7 |

Hello, world!

8 | 9 | Welcome to your new app. 10 | -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssembly/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter17/SourceGeneratorDemo/BlazorWebAssembly/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssembly/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter17/SourceGeneratorDemo/BlazorWebAssembly/wwwroot/icon-192.png -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/InterfaceGeneratorDemo/SampleService.cs: -------------------------------------------------------------------------------- 1 | namespace BlazorWebAssemblyApp.InterfaceGeneratorDemo; 2 | using InterfaceGenerator; 3 | 4 | [GenerateAutoInterface] 5 | public class SampleService: ISampleService 6 | { 7 | public double Multiply(double x, double y) 8 | { 9 | return x * y; 10 | } 11 | 12 | public int NiceNumber => 69; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @inject GeneratedService service 3 |

@service.GetHello()

4 | 5 | Welcome to your new app. 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter17/SourceGeneratorDemo/BlazorWebAssemblyApp/wwwroot/icon-192.png -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/App.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace BlazorHybridApp 2 | { 3 | public partial class App : Application 4 | { 5 | public App() 6 | { 7 | InitializeComponent(); 8 | 9 | MainPage = new MainPage(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Components/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 |

Counter

4 | 5 |

Current count: @currentCount

6 | 7 | 8 | 9 | @code { 10 | private int currentCount = 0; 11 | 12 | private void IncrementCount() 13 | { 14 | currentCount++; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 |

Hello, world!

4 | 5 | Welcome to your new app. 6 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace BlazorHybridApp 2 | { 3 | public partial class MainPage : ContentPage 4 | { 5 | public MainPage() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Platforms/Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #512BD4 4 | #2B0B98 5 | #2B0B98 6 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Platforms/MacCatalyst/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | 3 | namespace BlazorHybridApp 4 | { 5 | [Register("AppDelegate")] 6 | public class AppDelegate : MauiUIApplicationDelegate 7 | { 8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Platforms/Windows/App.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Platforms/iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | 3 | namespace BlazorHybridApp 4 | { 5 | [Register("AppDelegate")] 6 | public class AppDelegate : MauiUIApplicationDelegate 7 | { 8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Windows Machine": { 4 | "commandName": "MsixPackage", 5 | "nativeDebugging": false 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Resources/AppIcon/appicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Resources/Fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter18/BlazorHybridApp/BlazorHybridApp/Resources/Fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.Web.Virtualization 7 | @using Microsoft.JSInterop 8 | @using BlazorHybridApp 9 | @using BlazorHybridApp.Components 10 | -------------------------------------------------------------------------------- /Chapter18/BlazorHybridApp/BlazorHybridApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/Chapter18/BlazorHybridApp/BlazorHybridApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /Data/Categories/Category1.json: -------------------------------------------------------------------------------- 1 | {"Id":"Category1","Name":"Category Name 1"} -------------------------------------------------------------------------------- /Data/Categories/f23ad71a-6b8c-4f25-9e0f-667211bf29df.json: -------------------------------------------------------------------------------- 1 | {"Id":"f23ad71a-6b8c-4f25-9e0f-667211bf29df","Name":"Test"} -------------------------------------------------------------------------------- /Data/Comments/22ecaf2f-e056-4930-adb6-c2821ba3d54d.json: -------------------------------------------------------------------------------- 1 | {"Id":"22ecaf2f-e056-4930-adb6-c2821ba3d54d","BlogPostId":"BellaGreenHaven","Date":"2023-12-19T21:57:10.1541532+01:00","Text":"l\u00F6k\u00F6lk","Name":"klk\u00F6lk"} -------------------------------------------------------------------------------- /Data/Comments/30102fc1-6181-48d8-ac74-14ad0408c5f7.json: -------------------------------------------------------------------------------- 1 | {"Id":"30102fc1-6181-48d8-ac74-14ad0408c5f7","BlogPostId":"BellaGreenHaven","Date":"2023-12-18T20:54:44.7994045+01:00","Text":"ll","Name":"ll"} -------------------------------------------------------------------------------- /Data/Comments/5233b24f-0d62-4353-b956-43cde805d478.json: -------------------------------------------------------------------------------- 1 | {"Id":"5233b24f-0d62-4353-b956-43cde805d478","BlogPostId":"BellaGreenHaven","Date":"2023-12-19T21:38:25.6438176+01:00","Text":"\u00E4\u00F6l\u00E4\u00F6","Name":"\u00F6\u00E4\u00F6l\u00F6"} -------------------------------------------------------------------------------- /Data/Comments/719c89e1-106d-48f2-a9ed-6cc77ccd29d3.json: -------------------------------------------------------------------------------- 1 | {"Id":"719c89e1-106d-48f2-a9ed-6cc77ccd29d3","BlogPostId":"BellaGreenHaven","Date":"2023-12-18T20:51:07.9800761+01:00","Text":"lll","Name":""} -------------------------------------------------------------------------------- /Data/Comments/84f95c0c-0d3b-432f-b528-4b183a52f4fc.json: -------------------------------------------------------------------------------- 1 | {"Id":"84f95c0c-0d3b-432f-b528-4b183a52f4fc","BlogPostId":"BellaGreenHaven","Date":"2023-12-19T21:56:34.2946001+01:00","Text":"l\u00F6k\u00F6kl","Name":"\u00F6lk\u00F6kl"} -------------------------------------------------------------------------------- /Data/Comments/97c702a2-5a73-4ba5-ab9f-e8ec5c7bc891.json: -------------------------------------------------------------------------------- 1 | {"Id":"97c702a2-5a73-4ba5-ab9f-e8ec5c7bc891","BlogPostId":"BellaGreenHaven","Date":"2023-12-20T20:46:59.0151591+01:00","Text":"l\u00F6klk","Name":"lk\u00F6l"} -------------------------------------------------------------------------------- /Data/Comments/ea40b9e5-0db4-46dd-89f6-94759dc169a4.json: -------------------------------------------------------------------------------- 1 | {"Id":"ea40b9e5-0db4-46dd-89f6-94759dc169a4","BlogPostId":"BellaGreenHaven","Date":"2023-12-18T20:48:27.8419373+01:00","Text":"Awesome post!","Name":""} -------------------------------------------------------------------------------- /Data/Tags/f19cd19f-d0f7-4198-9a6e-98028b98104c.json: -------------------------------------------------------------------------------- 1 | {"Id":"f19cd19f-d0f7-4198-9a6e-98028b98104c","Name":"ljklkj"} -------------------------------------------------------------------------------- /Data/Tags/f96aafe5-8369-4fc9-b169-70b93d962cc8.json: -------------------------------------------------------------------------------- 1 | {"Id":"f96aafe5-8369-4fc9-b169-70b93d962cc8","Name":"test2"} -------------------------------------------------------------------------------- /ExampleData/Categories/Category1.json: -------------------------------------------------------------------------------- 1 | {"Id":"Category1","Name":"Category Name 1"} -------------------------------------------------------------------------------- /ExampleData/Images/BellaGreenHaven_Story.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/ExampleData/Images/BellaGreenHaven_Story.webp -------------------------------------------------------------------------------- /ExampleData/Images/EllieRainbowBrush_Story.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/ExampleData/Images/EllieRainbowBrush_Story.webp -------------------------------------------------------------------------------- /ExampleData/Images/JasperCityLightsAdventure_Story.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/ExampleData/Images/JasperCityLightsAdventure_Story.webp -------------------------------------------------------------------------------- /ExampleData/Images/OliverStarryQuest_Story.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/ExampleData/Images/OliverStarryQuest_Story.webp -------------------------------------------------------------------------------- /ExampleData/Images/RickyTheRaccoon_Story.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/ExampleData/Images/RickyTheRaccoon_Story.webp -------------------------------------------------------------------------------- /ExampleData/Images/RockyTheHeroRaccoon_Story.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/ExampleData/Images/RockyTheHeroRaccoon_Story.webp -------------------------------------------------------------------------------- /ExampleData/Images/RoxieTheMusicalRaccoon_Story.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/ExampleData/Images/RoxieTheMusicalRaccoon_Story.webp -------------------------------------------------------------------------------- /ExampleData/Images/WhiskersSecretGarden_Story.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Web-Development-with-Blazor-Third-Edition/39418e9c607d9a221e4ada2bff39b638c3f6c271/ExampleData/Images/WhiskersSecretGarden_Story.webp -------------------------------------------------------------------------------- /ExampleData/Tags/Tag1.json: -------------------------------------------------------------------------------- 1 | {"Id":"Tag1","Name":"Tag Name 1"} --------------------------------------------------------------------------------