Skip to content

Commit 835cad6

Browse files
authored
Merge pull request #36493 from dotnet/main
Merge to Live
2 parents 66e15cb + 3c3d46e commit 835cad6

87 files changed

Lines changed: 483 additions & 389 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
File renamed without changes.

aspnetcore/blazor/call-web-api.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,12 @@ Example:
5757

5858
In the app's `Program` file, call:
5959

60-
<!-- UPDATE 10.0 - Missing API doc for 'Microsoft.Identity.Web.DownstreamApiExtensions.AddDownstreamApi' -->
60+
<!-- UPDATE 11.0 - Awaiting API per https://github.com/dotnet/AspNetCore.Docs/issues/36373.
61+
Marking this for 11.0 because it's the last 10.0 item and inline tracking
62+
now adopts 11.0 or later work items. This ensures that this inline item
63+
isn't missed.
64+
65+
Missing API doc for 'Microsoft.Identity.Web.DownstreamApiExtensions.AddDownstreamApi' -->
6166

6267
* <xref:Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilder.EnableTokenAcquisitionToCallDownstreamApi%2A>: Enables token acquisition to call web APIs.
6368
* `AddDownstreamApi`: Microsoft Identity Web packages provide API to create a named downstream web service for making web API calls. <xref:Microsoft.Identity.Abstractions.IDownstreamApi> is injected into a server-side class, which is used to call <xref:Microsoft.Identity.Abstractions.IDownstreamApi.CallApiForUserAsync%2A> to obtain weather data from an external web API (`MinimalApiJwt` project).
@@ -194,7 +199,7 @@ builder.Services.AddDataProtection()
194199
`{KEY IDENTIFIER}`: Azure Key Vault key identifier used for key encryption. An access policy allows the application to access the key vault with `Get`, `Unwrap Key`, and `Wrap Key` permissions. The key identifier is obtained from the key in the Entra or Azure portal after it's created. If you enable autorotation of the key vault key, make sure that you use a versionless key identifier in the app's key vault configuration, where no key GUID is placed at the end of the identifier (example: `https://contoso.vault.azure.net/keys/data-protection`).
195200
196201
> [!NOTE]
197-
> In non-Production environments, the preceding example uses <xref:Azure.Identity.DefaultAzureCredential> to simplify authentication while developing apps that deploy to Azure by combining credentials used in Azure hosting environments with credentials used in local development. When moving to production, an alternative is a better choice, such as the <xref:Azure.Identity.ManagedIdentityCredential> shown in the preceding example. For more information, see [Authenticate Azure-hosted .NET apps to Azure resources using a system-assigned managed identity](/dotnet/azure/sdk/authentication/system-assigned-managed-identity).
202+
> In non-`Production` environments, the preceding example uses <xref:Azure.Identity.DefaultAzureCredential> to simplify authentication while developing apps that deploy to Azure by combining credentials used in Azure hosting environments with credentials used in local development. When moving to production, an alternative is a better choice, such as the <xref:Azure.Identity.ManagedIdentityCredential> shown in the preceding example. For more information, see [Authenticate Azure-hosted .NET apps to Azure resources using a system-assigned managed identity](/dotnet/azure/sdk/authentication/system-assigned-managed-identity).
198203
199204
Inject <xref:Microsoft.Identity.Abstractions.IDownstreamApi> and call <xref:Microsoft.Identity.Abstractions.IDownstreamApi.CallApiForUserAsync%2A> when calling on behalf of a user:
200205

aspnetcore/blazor/components/data-binding.md

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,16 +221,38 @@ Additional examples
221221

222222
For more information on the `InputText` component, see <xref:blazor/forms/input-components>.
223223

224-
Components support two-way data binding by defining a pair of `@bind` attributes with either a `:get` or `:set` modifier . The `{PARAMETER}` placeholder in the following examples is used to bind a component parameter:
224+
Components support two-way data binding by defining a pair of `@bind` attributes with either a `:get` or `:set` modifier. The `{PARAMETER}` placeholder in the following examples is used to bind a component parameter:
225225

226226
* `@bind:get`/`@bind-{PARAMETER}:get`: Specifies the value to bind.
227227
* `@bind:set`/`@bind-{PARAMETER}:set`: Specifies a callback for when the value changes.
228228

229-
The `:get` and `:set` modifiers are always used together.
229+
The `:get`/`:set` modifiers are always used together.
230230

231-
With `:get`/`:set` binding, you can react to a value change before it's applied to the DOM, and you can change the applied value, if necessary. Whereas with `@bind:event="{EVENT}"` attribute binding, where the `{EVENT}` placeholder is a DOM event, you receive the notification after the DOM is updated, and there's no capacity to modify the applied value while binding.
231+
For binding to HTML elements, use `:get`/`:set` modifiers to ensure an `<input>` element stays synchronized with a bound value, even when the value is modified in the handler:
232232

233-
The following `BindGetSet` component demonstrates `@bind:get`/`@bind:set` syntax for `<input>` elements and the [`InputText` component](xref:blazor/forms/input-components) used by [Blazor forms](xref:blazor/forms/index) in synchronous (`Set`) and asynchronous (`SetAsync`) scenarios.
233+
```razor
234+
<input @bind:get="inputValue" @bind:set="HandleValueChange" />
235+
```
236+
237+
> [!NOTE]
238+
> The legacy approach prior to the release of .NET 7 used the `value` attribute with `@onchange`:
239+
>
240+
> ```razor
241+
> <input value="@inputValue" @onchange="HandleValueChange" />
242+
> ```
243+
>
244+
> The preceding approach can cause synchronization errors, where the `<input>` element displays a different value than the value held in the bound variable. Migrate to `:get`/`:set` modifiers to avoid this issue.
245+
246+
For component parameters, the following syntaxes for a hypothetical `Child` component are functionally equivalent:
247+
248+
```razor
249+
<Child Value="@inputValue" ValueChanged="@(v => inputValue = v)" />
250+
<Child @bind-Value:get="inputValue" @bind-Value:set="@(v => inputValue = v)" />
251+
```
252+
253+
With `:get`/`:set` modifier binding, you can react to a value change before it's applied to the DOM, and you can change the applied value, if necessary. Whereas with `@bind:event="{EVENT}"` attribute binding, where the `{EVENT}` placeholder is a DOM event, you receive the notification after the DOM is updated, and there's no capacity to modify the applied value while binding.
254+
255+
The following `BindGetSet` component demonstrates `:get`/`:set` syntax for `<input>` elements and the [`InputText` component](xref:blazor/forms/input-components) used by [Blazor forms](xref:blazor/forms/index) in synchronous (`Set`) and asynchronous (`SetAsync`) scenarios.
234256

235257
`BindGetSet.razor`:
236258

@@ -270,7 +292,7 @@ The following `BindGetSet` component demonstrates `@bind:get`/`@bind:set` syntax
270292

271293
For more information on the `InputText` component, see <xref:blazor/forms/input-components>.
272294

273-
For another example use of `@bind:get` and `@bind:set`, see the [Bind across more than two components](#bind-across-more-than-two-components) section later in this article.
295+
For another example use of `:get` and `:set` modifiers, see the [Bind across more than two components](#bind-across-more-than-two-components) section later in this article.
274296

275297
Razor attribute binding is case-sensitive:
276298

@@ -279,7 +301,7 @@ Razor attribute binding is case-sensitive:
279301

280302
## Use `@bind:get`/`@bind:set` modifiers and avoid event handlers for two-way data binding
281303

282-
Two-way data binding isn't possible to implement with an event handler. Use `@bind:get`/`@bind:set` modifiers for two-way data binding.
304+
Two-way data binding isn't possible to implement with an event handler. Use `:get`/`:set` modifiers for two-way data binding.
283305

284306
<span aria-hidden="true">❌</span> Consider the following ***dysfunctional approach*** for two-way data binding using an event handler:
285307

@@ -306,9 +328,9 @@ Two-way data binding isn't possible to implement with an event handler. Use `@bi
306328

307329
The `OnInput` event handler updates the value of `inputValue` to `Long!` after a fourth character is provided. However, the user can continue adding characters to the element value in the UI. The value of `inputValue` isn't bound back to the element's value with each keystroke. The preceding example is only capable of one-way data binding.
308330

309-
The reason for this behavior is that Blazor isn't aware that your code intends to modify the value of `inputValue` in the event handler. Blazor doesn't try to force DOM element values and .NET variable values to match unless they're bound with `@bind` syntax. In earlier versions of Blazor, two-way data binding is implemented by [binding the element to a property and controlling the property's value with its setter](#binding-to-a-property-with-c-get-and-set-accessors). In ASP.NET Core in .NET 7 or later, `@bind:get`/`@bind:set` modifier syntax is used to implement two-way data binding, as the next example demonstrates.
331+
The reason for this behavior is that Blazor isn't aware that your code intends to modify the value of `inputValue` in the event handler. Blazor doesn't try to force DOM element values and .NET variable values to match unless they're bound with `@bind` syntax. In earlier versions of Blazor, two-way data binding is implemented by [binding the element to a property and controlling the property's value with its setter](#binding-to-a-property-with-c-get-and-set-accessors). In ASP.NET Core in .NET 7 or later, `:get`/`:set` modifier syntax is used to implement two-way data binding, as the next example demonstrates.
310332

311-
<span aria-hidden="true">✔️</span> Consider the following ***correct approach*** using `@bind:get`/`@bind:set` for two-way data binding:
333+
<span aria-hidden="true">✔️</span> Consider the following ***correct approach*** using `:get`/`:set` for two-way data binding:
312334

313335
```razor
314336
<p>
@@ -331,7 +353,7 @@ The reason for this behavior is that Blazor isn't aware that your code intends t
331353
}
332354
```
333355

334-
Using `@bind:get`/`@bind:set` modifiers both controls the underlying value of `inputValue` via `@bind:set` and binds the value of `inputValue` to the element's value via `@bind:get`. The preceding example demonstrates the correct approach for implementing two-way data binding.
356+
Using `:get`/`:set` modifiers both controls the underlying value of `inputValue` via `:set` and binds the value of `inputValue` to the element's value via `:get`. The preceding example demonstrates the correct approach for implementing two-way data binding.
335357

336358
:::moniker-end
337359

aspnetcore/blazor/components/quickgrid.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ With the **Add New Scaffold Item** dialog open to **Installed** > **Common** > *
477477

478478
Complete the **Add Razor Components using Entity Framework (CRUD)** dialog:
479479

480-
<!-- UPDATE 10.0 Keep an eye on https://github.com/dotnet/Scaffolding/issues/3131
480+
<!-- UPDATE 11.0 Keep an eye on https://github.com/dotnet/Scaffolding/issues/3131
481481
for a scaffolding update that makes the scaffolder a little
482482
smarter about suggesting an existing dB context that has a
483483
factory provider. If the scaffolder can do that, this instruction

aspnetcore/blazor/forms/validation.md

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,27 +1576,23 @@ The <xref:System.ComponentModel.DataAnnotations.CompareAttribute> doesn't work w
15761576

15771577
Blazor form validation includes support for validating properties of nested objects and collection items with the built-in <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator>.
15781578

1579-
To create a validated form, use a <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component inside an <xref:Microsoft.AspNetCore.Components.Forms.EditForm> component, just as before.
1579+
To create a validated form, use a <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component inside an <xref:Microsoft.AspNetCore.Components.Forms.EditForm> component.
15801580

15811581
To opt into the nested objects and collection types validation feature:
15821582

15831583
1. Call the <xref:Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation%2A> extension method in the `Program` file where services are registered.
15841584
2. Declare the form model types in a C# class file, not in a Razor component (`.razor`).
15851585
3. Annotate the root form model type with the [`[ValidatableType]` attribute](xref:Microsoft.Extensions.Validation.ValidatableTypeAttribute).
15861586

1587-
Without following the preceding steps, form validation behavior doesn't include nested model and collection type validation.
1588-
1589-
<!-- UPDATE 10.0 - Replace with a fully working, cut-'n-paste example -->
1590-
1591-
The following example demonstrates customer orders with the improved form validation (details omitted for brevity):
1587+
The following example demonstrates customer orders with nested collection form validation.
15921588

15931589
In `Program.cs`, call <xref:Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation%2A> on the service collection:
15941590

15951591
```csharp
15961592
builder.Services.AddValidation();
15971593
```
15981594

1599-
In the following `Order` class, the `[ValidatableType]` attribute is required on the top-level model type. The other types are discovered automatically. `OrderItem` and `ShippingAddress` aren't shown for brevity, but nested and collection validation works the same way in those types if they were shown.
1595+
In the following `Order` class, the `[ValidatableType]` attribute is required on the top-level model type. The other types are discovered automatically.
16001596

16011597
`Order.cs`:
16021598

@@ -1622,6 +1618,41 @@ public class Customer
16221618
}
16231619
```
16241620

1621+
`OrderItem.cs`:
1622+
1623+
```csharp
1624+
public class OrderItem
1625+
{
1626+
[Required(ErrorMessage = "Id is required.")]
1627+
public int Id { get; set; }
1628+
1629+
[Required(ErrorMessage = "Description is required.")]
1630+
public string? Description { get; set; }
1631+
1632+
[Required(ErrorMessage = "Price is required.")]
1633+
public decimal Price { get; set; }
1634+
}
1635+
```
1636+
1637+
`ShippingAddress.cs`:
1638+
1639+
```csharp
1640+
public class ShippingAddress
1641+
{
1642+
[Required(ErrorMessage = "Street is required.")]
1643+
public string? Street { get; set; }
1644+
1645+
[Required(ErrorMessage = "City is required.")]
1646+
public string? City { get; set; }
1647+
1648+
[Required(ErrorMessage = "State/Province is required.")]
1649+
public string? StateProvince { get; set; }
1650+
1651+
[Required(ErrorMessage = "PostalCode is required.")]
1652+
public string? PostalCode { get; set; }
1653+
}
1654+
```
1655+
16251656
In the following `OrderPage` component, the <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component is present in the <xref:Microsoft.AspNetCore.Components.Forms.EditForm> component.
16261657

16271658
`OrderPage.razor`:
@@ -1649,7 +1680,7 @@ In the following `OrderPage` component, the <xref:Microsoft.AspNetCore.Component
16491680
}
16501681
```
16511682

1652-
The requirement to declare the model types outside of Razor components (`.razor` files) is due to the fact that both the new validation feature and the Razor compiler itself are using a source generator. Currently, output of one source generator can't be used as an input for another source generator.
1683+
The requirement to declare the model types outside of Razor components (`.razor` files) is due to the fact that both the nested collection validation feature and the Razor compiler itself are using a source generator. Currently, output of one source generator can't be used as an input for another source generator.
16531684

16541685
For guidance on using validation models from a different assembly, see the [Use validation models from a different assembly](#use-validation-models-from-a-different-assembly) section.
16551686

0 commit comments

Comments
 (0)