From dbf0e75bfaf84fa6f79e551adb3a4897b78f8d07 Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Wed, 8 Dec 2021 07:30:31 -0600
Subject: [PATCH 1/5] Blazor app pool guidance
---
aspnetcore/blazor/host-and-deploy/index.md | 18 ++++++++++++++++++
aspnetcore/host-and-deploy/iis/web-config.md | 2 +-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/aspnetcore/blazor/host-and-deploy/index.md b/aspnetcore/blazor/host-and-deploy/index.md
index dd26f2d6c796..643304b84e26 100644
--- a/aspnetcore/blazor/host-and-deploy/index.md
+++ b/aspnetcore/blazor/host-and-deploy/index.md
@@ -52,6 +52,12 @@ Publish locations:
The assets in the folder are deployed to the web server. Deployment might be a manual or automated process depending on the development tools in use.
+## IIS Application Pools
+
+Sharing an app pool among ASP.NET Core apps isn't supported, including for Blazor apps. Use one app pool per app when hosting with IIS, and avoid the use of IIS's [virtual directories](/iis/get-started/planning-your-iis-architecture/understanding-sites-applications-and-virtual-directories-on-iis#virtual-directories) for hosting multiple apps.
+
+One or more Blazor WebAssembly apps hosted by an ASP.NET Core app, known as a [hosted Blazor WebAssembly solution](xref:blazor/hosting-models#blazor-webassembly), are supported for ***one*** app pool. However, we don't recommend or support assigning a single app pool to multiple hosted Blazor WebAssembly solutions or in sub-app hosting scenarios. For more information, see .
+
## App base path
The *app base path* is the app's root URL path. Consider the following ASP.NET Core app and Blazor sub-app:
@@ -211,6 +217,12 @@ Publish locations:
The assets in the folder are deployed to the web server. Deployment might be a manual or automated process depending on the development tools in use.
+## IIS Application Pools
+
+Sharing an app pool among ASP.NET Core apps isn't supported, including for Blazor apps. Use one app pool per app when hosting with IIS, and avoid the use of IIS's [virtual directories](/iis/get-started/planning-your-iis-architecture/understanding-sites-applications-and-virtual-directories-on-iis#virtual-directories) for hosting multiple apps.
+
+One or more Blazor WebAssembly apps hosted by an ASP.NET Core app, known as a [hosted Blazor WebAssembly solution](xref:blazor/hosting-models#blazor-webassembly), are supported for ***one*** app pool. However, we don't recommend or support assigning a single app pool to multiple hosted Blazor WebAssembly solutions or in sub-app hosting scenarios. For more information, see .
+
## App base path
The *app base path* is the app's root URL path. Consider the following ASP.NET Core app and Blazor sub-app:
@@ -350,6 +362,12 @@ Publish locations:
The assets in the folder are deployed to the web server. Deployment might be a manual or automated process depending on the development tools in use.
+## IIS Application Pools
+
+Sharing an app pool among ASP.NET Core apps isn't supported, including for Blazor apps. Use one app pool per app when hosting with IIS, and avoid the use of IIS's [virtual directories](/iis/get-started/planning-your-iis-architecture/understanding-sites-applications-and-virtual-directories-on-iis#virtual-directories) for hosting multiple apps.
+
+One or more Blazor WebAssembly apps hosted by an ASP.NET Core app, known as a [hosted Blazor WebAssembly solution](xref:blazor/hosting-models#blazor-webassembly), are supported for ***one*** app pool. However, we don't recommend or support assigning a single app pool to multiple hosted Blazor WebAssembly solutions or in sub-app hosting scenarios. For more information, see .
+
## App base path
The *app base path* is the app's root URL path. Consider the following ASP.NET Core app and Blazor sub-app:
diff --git a/aspnetcore/host-and-deploy/iis/web-config.md b/aspnetcore/host-and-deploy/iis/web-config.md
index c4bee8a6b974..def9d7db062f 100644
--- a/aspnetcore/host-and-deploy/iis/web-config.md
+++ b/aspnetcore/host-and-deploy/iis/web-config.md
@@ -90,7 +90,7 @@ The
When an app is deployed to [Azure App Service](https://azure.microsoft.com/services/app-service/), the `stdoutLogFile` path is set to `\\?\%home%\LogFiles\stdout`. The path saves stdout logs to the `LogFiles` folder, which is a location automatically created by the service.
-For information on IIS sub-application configuration, see .
+For information on IIS sub-application configuration, see .
### Attributes of the `aspNetCore` element
From 5a207bd7c045c6f1775f322bb7ea1fd769795ea1 Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Thu, 9 Dec 2021 14:14:42 -0600
Subject: [PATCH 2/5] Blazor 6.0 examples to snippet samps + NRT work
---
.../cascading-values-and-parameters.md | 32 ++++-----
.../blazor/components/class-libraries.md | 4 ++
.../blazor/components/control-head-content.md | 25 +------
aspnetcore/blazor/components/data-binding.md | 5 +-
.../blazor/components/dynamiccomponent.md | 66 +++++++++----------
.../ControlHeadContent.razor | 22 +++++++
.../ControlHeadContent.razor | 22 +++++++
7 files changed, 99 insertions(+), 77 deletions(-)
create mode 100644 aspnetcore/blazor/samples/6.0/BlazorSample_Server/Pages/control-head-content/ControlHeadContent.razor
create mode 100644 aspnetcore/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/control-head-content/ControlHeadContent.razor
diff --git a/aspnetcore/blazor/components/cascading-values-and-parameters.md b/aspnetcore/blazor/components/cascading-values-and-parameters.md
index d5c9d4911379..333a8851afb9 100644
--- a/aspnetcore/blazor/components/cascading-values-and-parameters.md
+++ b/aspnetcore/blazor/components/cascading-values-and-parameters.md
@@ -60,26 +60,22 @@ In the following example, two [`CascadingValue`](xref:Microsoft.AspNetCore.Compo
@code {
- private CascadingType parentCascadeParameter1;
+ private CascadingType? parentCascadeParameter1;
[Parameter]
- public CascadingType ParentCascadeParameter2 { get; set; }
-
- ...
+ public CascadingType? ParentCascadeParameter2 { get; set; }
}
```
In a descendant component, the cascaded parameters receive their cascaded values from the ancestor component by :
```razor
-...
-
@code {
[CascadingParameter(Name = "CascadeParam1")]
- protected CascadingType ChildCascadeParameter1 { get; set; }
+ protected CascadingType? ChildCascadeParameter1 { get; set; }
[CascadingParameter(Name = "CascadeParam2")]
- protected CascadingType ChildCascadeParameter2 { get; set; }
+ protected CascadingType? ChildCascadeParameter2 { get; set; }
}
```
@@ -131,13 +127,13 @@ Child `Tab` components aren't explicitly passed as parameters to the `TabSet`. I
@code {
[Parameter]
- public RenderFragment ChildContent { get; set; }
+ public RenderFragment? ChildContent { get; set; }
- public ITab ActiveTab { get; private set; }
+ public ITab? ActiveTab { get; private set; }
public void AddTab(ITab tab)
{
- if (ActiveTab == null)
+ if (ActiveTab is null)
{
SetActiveTab(tab);
}
@@ -170,25 +166,25 @@ Descendent `Tab` components capture the containing `TabSet` as a cascading param
@code {
[CascadingParameter]
- public TabSet ContainerTabSet { get; set; }
+ public TabSet? ContainerTabSet { get; set; }
[Parameter]
- public string Title { get; set; }
+ public string? Title { get; set; }
[Parameter]
- public RenderFragment ChildContent { get; set; }
+ public RenderFragment? ChildContent { get; set; }
- private string TitleCssClass =>
- ContainerTabSet.ActiveTab == this ? "active" : null;
+ private string? TitleCssClass =>
+ ContainerTabSet?.ActiveTab == this ? "active" : null;
protected override void OnInitialized()
{
- ContainerTabSet.AddTab(this);
+ ContainerTabSet?.AddTab(this);
}
private void ActivateTab()
{
- ContainerTabSet.SetActiveTab(this);
+ ContainerTabSet?.SetActiveTab(this);
}
}
```
diff --git a/aspnetcore/blazor/components/class-libraries.md b/aspnetcore/blazor/components/class-libraries.md
index 399c68ba7250..a3db074b089a 100644
--- a/aspnetcore/blazor/components/class-libraries.md
+++ b/aspnetcore/blazor/components/class-libraries.md
@@ -340,6 +340,10 @@ Blazor WebAssembly and RCL projects *automatically* enable browser compatibility
When authoring a library, indicate that a particular API isn't supported in browsers by specifying `browser` to :
```csharp
+using System.Runtime.Versioning;
+
+...
+
[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{
diff --git a/aspnetcore/blazor/components/control-head-content.md b/aspnetcore/blazor/components/control-head-content.md
index 3e22815fc05a..6ba05dae183b 100644
--- a/aspnetcore/blazor/components/control-head-content.md
+++ b/aspnetcore/blazor/components/control-head-content.md
@@ -23,30 +23,7 @@ The following example sets the page's title and description using Razor.
`Pages/ControlHeadContent.razor`:
-```razor
-@page "/control-head-content"
-
-
Control <head> content
-
-
- Title: @title
-
-
-
- Description: @description
-
-
-@title
-
-
-
-
-
-@code {
- private string description = "Description set by component";
- private string title = "Title set by component";
-}
-```
+[!code-razor[](~/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/control-head-content/ControlHeadContent.razor?highlight=13,15-17)]
## Control head content during prerendering
diff --git a/aspnetcore/blazor/components/data-binding.md b/aspnetcore/blazor/components/data-binding.md
index bed8413fb99c..aae830094ec4 100644
--- a/aspnetcore/blazor/components/data-binding.md
+++ b/aspnetcore/blazor/components/data-binding.md
@@ -98,7 +98,10 @@ Binding supports [`multiple`](https://developer.mozilla.org/docs/Web/HTML/Attrib
void SelectedCarsChanged(ChangeEventArgs e)
{
- SelectedCars = (string[])e.Value;
+ if (e.Value is not null)
+ {
+ SelectedCars = (string[])e.Value;
+ }
}
}
```
diff --git a/aspnetcore/blazor/components/dynamiccomponent.md b/aspnetcore/blazor/components/dynamiccomponent.md
index d2f7e70a277a..c5aa82db6399 100644
--- a/aspnetcore/blazor/components/dynamiccomponent.md
+++ b/aspnetcore/blazor/components/dynamiccomponent.md
@@ -41,11 +41,11 @@ Use the propert
@code {
- private DynamicComponent dc;
+ private DynamicComponent? dc;
private Task Refresh()
{
- return (dc.Instance as IRefreshable)?.Refresh();
+ return (dc?.Instance as IRefreshable)?.Refresh();
}
}
```
@@ -138,11 +138,11 @@ In the following example, a Razor component renders a component based on the use
}
@code {
- private Type selectedType;
+ private Type? selectedType;
private void OnDropdownChange(ChangeEventArgs e)
{
- selectedType = e.Value.ToString().Length > 0 ?
+ selectedType = e.Value?.ToString()?.Length > 0 ?
Type.GetType($"{APP NAMESPACE}.Shared.{e.Value}") : null;
}
}
@@ -162,17 +162,37 @@ The following example configures a component metadata object (`ComponentMetadata
`ComponentMetadata.cs`:
```csharp
-using System;
-using System.Collections.Generic;
-
public class ComponentMetadata
{
- public string Name { get; set; }
- public Dictionary Parameters { get; set; }
+ public string? Name { get; set; }
+ public Dictionary Parameters { get; set; } =
+ new Dictionary();
+}
+```
+
+The following `RocketLab` component (`Shared/RocketLab.razor`) has been updated from the preceding example to include a component parameter named `WindowSeat` to specify if the passenger prefers a window seat on their flight:
+
+`Shared/RocketLab.razor`:
+
+```razor
+
+
+@code {
+ [Parameter]
+ public bool WindowSeat { get; set; }
}
```
-In the following example, only the `RocketLab` component has a parameter, which assigns a value for a window seat (`WindowSeat`) on a spaceflight.
+In the following example, only the `RocketLab` component's parameter for a window seat (`WindowSeat`) receives the value of the **`Window Seat`** checkbox.
`Pages/DynamicComponentExample2.razor`:
@@ -234,7 +254,7 @@ In the following example, only the `RocketLab` component has a parameter, which
new ComponentMetadata { Name = "SpaceX" }
}
};
- private Type selectedType;
+ private Type? selectedType;
private bool windowSeat;
private bool WindowSeat
@@ -249,7 +269,7 @@ In the following example, only the `RocketLab` component has a parameter, which
private void OnDropdownChange(ChangeEventArgs e)
{
- selectedType = e.Value.ToString().Length > 0 ?
+ selectedType = e.Value?.ToString()?.Length > 0 ?
Type.GetType($"{APP NAMESPACE}.Shared.{e.Value}") : null;
}
}
@@ -265,28 +285,6 @@ In the preceding example:
* `UnitedLaunchAlliance` (`Shared/UnitedLaunchAlliance.razor`)
* `VirginGalactic` (`Shared/VirginGalactic.razor`)
-The `RocketLab` component (`Shared/RocketLab.razor`) includes a component parameter named `WindowSeat`:
-
-`Shared/RocketLab.razor`:
-
-```razor
-
-
-@code {
- [Parameter]
- public bool WindowSeat { get; set; }
-}
-```
-
## Avoid catch-all parameters
Avoid the use of [catch-all parameters](xref:blazor/fundamentals/routing#catch-all-route-parameters). If catch-all parameters are used, every explicit parameter on effectively is a reserved word that you can't pass to a dynamic child. Any new parameters passed to are a breaking change, as they start shadowing child component parameters that happen to have the same name. It's unlikely that the caller always knows a fixed set of parameter names to pass to all possible dynamic children.
diff --git a/aspnetcore/blazor/samples/6.0/BlazorSample_Server/Pages/control-head-content/ControlHeadContent.razor b/aspnetcore/blazor/samples/6.0/BlazorSample_Server/Pages/control-head-content/ControlHeadContent.razor
new file mode 100644
index 000000000000..9f690a1580a2
--- /dev/null
+++ b/aspnetcore/blazor/samples/6.0/BlazorSample_Server/Pages/control-head-content/ControlHeadContent.razor
@@ -0,0 +1,22 @@
+@page "/control-head-content"
+
+
Control <head> content
+
+
+ Title: @title
+
+
+
+ Description: @description
+
+
+@title
+
+
+
+
+
+@code {
+ private string description = "Description set by component";
+ private string title = "Title set by component";
+}
diff --git a/aspnetcore/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/control-head-content/ControlHeadContent.razor b/aspnetcore/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/control-head-content/ControlHeadContent.razor
new file mode 100644
index 000000000000..9f690a1580a2
--- /dev/null
+++ b/aspnetcore/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/control-head-content/ControlHeadContent.razor
@@ -0,0 +1,22 @@
+@page "/control-head-content"
+
+
-}
-
-@code {
- private Type? selectedType;
-
- private void OnDropdownChange(ChangeEventArgs e)
- {
- selectedType = e.Value?.ToString()?.Length > 0 ?
- Type.GetType($"{APP NAMESPACE}.Shared.{e.Value}") : null;
- }
-}
-```
+[!code-razor[](~/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/dynamiccomponent/DynamicComponentExample1.razor)]
In the preceding example:
@@ -170,121 +108,27 @@ public class ComponentMetadata
}
```
-The following `RocketLab` component (`Shared/RocketLab.razor`) has been updated from the preceding example to include a component parameter named `WindowSeat` to specify if the passenger prefers a window seat on their flight:
-
-`Shared/RocketLab.razor`:
-
-```razor
-
Rocket Lab®
+The following `RocketLabWithWindowSeat` component (`Shared/RocketLabWithWindowSeat.razor`) has been updated from the preceding example to include a component parameter named `WindowSeat` to specify if the passenger prefers a window seat on their flight:
-
+[!code-razor[](~/blazor/samples/6.0/BlazorSample_WebAssembly/Shared/dynamiccomponent/RocketLabWithWindowSeat.razor?highlight=13-14)]
-@code {
- [Parameter]
- public bool WindowSeat { get; set; }
-}
-```
-
-In the following example, only the `RocketLab` component's parameter for a window seat (`WindowSeat`) receives the value of the **`Window Seat`** checkbox.
-
-`Pages/DynamicComponentExample2.razor`:
-
-```razor
-@page "/dynamiccomponent-example-2"
-
-
DynamicComponent Component Example 2
-
-
-
-
-
-
-
-
-
-@if (selectedType is not null)
-{
-
-
-
-}
-
-@code {
- private Dictionary components =
- new()
- {
- {
- "RocketLab",
- new ComponentMetadata
- {
- Name = "Rocket Lab",
- Parameters = new() { { "WindowSeat", false } }
- }
- },
- {
- "VirginGalactic",
- new ComponentMetadata { Name = "Virgin Galactic" }
- },
- {
- "UnitedLaunchAlliance",
- new ComponentMetadata { Name = "ULA" }
- },
- {
- "SpaceX",
- new ComponentMetadata { Name = "SpaceX" }
- }
- };
- private Type? selectedType;
- private bool windowSeat;
-
- private bool WindowSeat
- {
- get { return windowSeat; }
- set
- {
- windowSeat = value;
- components[nameof(RocketLab)].Parameters["WindowSeat"] = windowSeat;
- }
- }
-
- private void OnDropdownChange(ChangeEventArgs e)
- {
- selectedType = e.Value?.ToString()?.Length > 0 ?
- Type.GetType($"{APP NAMESPACE}.Shared.{e.Value}") : null;
- }
-}
-```
-
-In the preceding example:
+In the following example:
+* Only the `RocketLabWithWindowSeat` component's parameter for a window seat (`WindowSeat`) receives the value of the **`Window Seat`** checkbox.
* The `{APP NAMESPACE}` placeholder is the namespace of the app (for example, `BlazorSample`).
* The dynamically-rendered components are shared components in the app's `Shared` folder:
- * Shown in this article section: `RocketLab` (`Shared/RocketLab.razor`)
+ * Shown in this article section: `RocketLabWithWindowSeat` (`Shared/RocketLabWithWindowSeat.razor`)
* Components shown in the [Example](#example) section earlier in this article:
* `SpaceX` (`Shared/SpaceX.razor`)
* `UnitedLaunchAlliance` (`Shared/UnitedLaunchAlliance.razor`)
* `VirginGalactic` (`Shared/VirginGalactic.razor`)
+`Pages/DynamicComponentExample2.razor`:
+
+[!code-razor[](~/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/dynamiccomponent/DynamicComponentExample2.razor)]
+
## Avoid catch-all parameters
Avoid the use of [catch-all parameters](xref:blazor/fundamentals/routing#catch-all-route-parameters). If catch-all parameters are used, every explicit parameter on effectively is a reserved word that you can't pass to a dynamic child. Any new parameters passed to are a breaking change, as they start shadowing child component parameters that happen to have the same name. It's unlikely that the caller always knows a fixed set of parameter names to pass to all possible dynamic children.
diff --git a/aspnetcore/blazor/components/event-handling.md b/aspnetcore/blazor/components/event-handling.md
index 212009605188..dc0c90900140 100644
--- a/aspnetcore/blazor/components/event-handling.md
+++ b/aspnetcore/blazor/components/event-handling.md
@@ -114,8 +114,8 @@ Custom events with custom event arguments are generally enabled with the followi
```csharp
public class CustomEventArgs : EventArgs
{
- public string CustomProperty1 {get; set;}
- public string CustomProperty2 {get; set;}
+ public string? CustomProperty1 {get; set;}
+ public string? CustomProperty2 {get; set;}
}
```
@@ -165,7 +165,7 @@ public static class EventHandlers
public class CustomPasteEventArgs : EventArgs
{
public DateTime EventTimestamp { get; set; }
- public string PastedData { get; set; }
+ public string? PastedData { get; set; }
}
```
@@ -178,10 +178,10 @@ Add JavaScript code to supply data for the subclass. In
Blazor.registerCustomEventType('custompaste', {
browserEventName: 'paste',
createEventArgs: event => {
- return {
- eventTimestamp: new Date(),
- pastedData: event.clipboardData.getData('text')
- };
+ return {
+ eventTimestamp: new Date(),
+ pastedData: event.clipboardData.getData('text')
+ };
}
});
@@ -216,7 +216,7 @@ In a Razor component, attach the custom handler to an element.
@code {
- private string message;
+ private string? message;
private void HandleCustomPaste(CustomPasteEventArgs eventArgs)
{
diff --git a/aspnetcore/blazor/components/index.md b/aspnetcore/blazor/components/index.md
index 033c02a68df5..4a1e98d78ed4 100644
--- a/aspnetcore/blazor/components/index.md
+++ b/aspnetcore/blazor/components/index.md
@@ -158,32 +158,11 @@ The following `Counter` component splits HTML and Razor markup from C# code usi
`Pages/CounterPartialClass.razor`:
-```razor
-@page "/counter-partial-class"
-
-
Counter
-
-
Current count: @currentCount
-
-
-```
+[!code-razor[](~/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/index/CounterPartialClass.razor)]
`Pages/CounterPartialClass.razor.cs`:
-```csharp
-namespace BlazorSample.Pages
-{
- public partial class CounterPartialClass
- {
- private int currentCount = 0;
-
- void IncrementCount()
- {
- currentCount++;
- }
- }
-}
-```
+[!code-csharp[](~/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/index/CounterPartialClass.razor.cs)]
[`@using`][2] directives in the `_Imports.razor` file are only applied to Razor files (`.razor`), not C# files (`.cs`). Add namespaces to a partial class file as needed.
@@ -306,7 +285,7 @@ To obtain a value for the `Title` parameter in the preceding example asynchronou
@code {
- private string title;
+ private string? title;
protected override async Task OnInitializedAsync()
{
@@ -368,14 +347,14 @@ Apply the [`[EditorRequired]` attribute](xref:Microsoft.AspNetCore.Components.Ed
```csharp
[Parameter]
[EditorRequired]
-public string Title { get; set; }
+public string? Title { get; set; }
```
Single-line attribute lists are also supported:
```csharp
[Parameter, EditorRequired]
-public string Title { get; set; }
+public string? Title { get; set; }
```
## Route parameters
@@ -534,7 +513,7 @@ To accept arbitrary attributes, define a [component parameter](#component-parame
```razor
@code {
[Parameter(CaptureUnmatchedValues = true)]
- public Dictionary InputAttributes { get; set; }
+ public Dictionary? InputAttributes { get; set; }
}
```
@@ -971,7 +950,7 @@ The following example demonstrates:
private string message = "Lorem ipsum dolor sit amet, consectetur adipiscing " +
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
- private string value;
+ private string? value;
}
```
diff --git a/aspnetcore/blazor/components/lifecycle.md b/aspnetcore/blazor/components/lifecycle.md
index bf06b230aa9e..85690bedacc3 100644
--- a/aspnetcore/blazor/components/lifecycle.md
+++ b/aspnetcore/blazor/components/lifecycle.md
@@ -322,8 +322,9 @@ Unsubscribe event handlers from .NET events. The following [Blazor form](xref:bl
@code {
- // ...
- private EventHandler fieldChanged;
+ ...
+
+ private EventHandler? fieldChanged;
protected override void OnInitialized()
{
@@ -331,7 +332,7 @@ Unsubscribe event handlers from .NET events. The following [Blazor form](xref:bl
fieldChanged = (_, __) =>
{
- // ...
+ ...
};
editContext.OnFieldChanged += fieldChanged;
@@ -355,7 +356,7 @@ Unsubscribe event handlers from .NET events. The following [Blazor form](xref:bl
@code {
- // ...
+ ...
protected override void OnInitialized()
{
@@ -365,7 +366,7 @@ Unsubscribe event handlers from .NET events. The following [Blazor form](xref:bl
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
{
- // ...
+ ...
}
public void Dispose()
@@ -398,10 +399,10 @@ When [anonymous functions](/dotnet/csharp/programming-guide/statements-expressio
* Anonymous lambda expression approach (explicit disposal not required):
```csharp
- private ValidationMessageStore messageStore;
+ private ValidationMessageStore? messageStore;
[CascadingParameter]
- private EditContext CurrentEditContext { get; set; }
+ private EditContext? CurrentEditContext { get; set; }
protected override void OnInitialized()
{
diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md
index c93678e1319d..f7076a7e8090 100644
--- a/aspnetcore/blazor/components/prerendering-and-integration.md
+++ b/aspnetcore/blazor/components/prerendering-and-integration.md
@@ -576,6 +576,8 @@ To support routable Razor components in Razor Pages apps:
```razor
@page "/routable-counter"
+ Routable Counter
+
Routable Counter
Current count: @currentCount
@@ -672,6 +674,8 @@ To support routable Razor components in MVC apps:
```razor
@page "/routable-counter"
+ Routable Counter
+
Routable Counter
Current count: @currentCount
@@ -711,7 +715,7 @@ When the page or view renders:
The following Razor page renders a `Counter` component:
```cshtml
-
My Razor Page
+
Razor Page
@@ -732,7 +736,7 @@ For more information, see My Razor Page
+