Compare commits
18 Commits
minorCorre
...
master
Author | SHA1 | Date |
---|---|---|
|
f2a83a1823 | 3 months ago |
|
fd9502cab4 | 3 months ago |
|
18af06f563 | 1 year ago |
![]() |
2e39213c97 | 2 years ago |
![]() |
97fa5ef0fe | 2 years ago |
![]() |
5a2def8b68 | 2 years ago |
![]() |
63731015ac | 2 years ago |
![]() |
62188b1c55 | 2 years ago |
![]() |
b7430749a7 | 2 years ago |
![]() |
2eeceb9c7c | 2 years ago |
![]() |
40174bb63d | 2 years ago |
![]() |
6394b28704 | 2 years ago |
![]() |
055c868ce9 | 2 years ago |
![]() |
aa4cadf5d6 | 2 years ago |
![]() |
b509aa824f | 2 years ago |
![]() |
cfef683d7a | 2 years ago |
![]() |
9f0ee156f9 | 2 years ago |
![]() |
649d0731a1 | 2 years ago |
@ -1,161 +1,161 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
title: Creation of the add model
|
||||
---
|
||||
|
||||
## Add model
|
||||
|
||||
In order to add an element we will create an object representing our item.
|
||||
|
||||
For this in create a new class `Models/ItemModel.cs`, this class will include all the information of our API object.
|
||||
|
||||
We will also add a property so that the user accepts the conditions of addition.
|
||||
|
||||
Similarly, annotations will be present to validate the fields of our forms.
|
||||
|
||||
```csharp title="Models/ItemModel.cs"
|
||||
public class ItemModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(50, ErrorMessage = "The display name must not exceed 50 characters.")]
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(50, ErrorMessage = "The name must not exceed 50 characters.")]
|
||||
[RegularExpression(@"^[a-z''-'\s]{1,40}$", ErrorMessage = "Only lowercase characters are accepted.")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[Range(1, 64)]
|
||||
public int StackSize { get; set; }
|
||||
|
||||
[Required]
|
||||
[Range(1, 125)]
|
||||
public int MaxDurability { get; set; }
|
||||
|
||||
public List<string> EnchantCategories { get; set; }
|
||||
|
||||
public List<string> RepairWith { get; set; }
|
||||
|
||||
[Required]
|
||||
[Range(typeof(bool), "true", "true", ErrorMessage = "You must agree to the terms.")]
|
||||
public bool AcceptCondition { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "The image of the item is mandatory!")]
|
||||
public byte[] ImageContent { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
## Concept: Data Annotation
|
||||
|
||||
### Validation attributes
|
||||
|
||||
Validation attributes allow you to specify validation rules for model properties.
|
||||
|
||||
The following example shows a model class that is annotated with validation attributes.
|
||||
The `[ClassicMovie]` attribute is a custom validation attribute, and the others are predefined.
|
||||
|
||||
```csharp
|
||||
public class Movie
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Title { get; set; }
|
||||
|
||||
[ClassicMovie(1960)]
|
||||
[DataType(DataType.Date)]
|
||||
[Display(Name = "Release Date")]
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(1000)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Range(0, 999.99)]
|
||||
public decimal Price { get; set; }
|
||||
|
||||
public Genre Genre { get; set; }
|
||||
|
||||
public bool Preorder { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
### Attributs prédéfinis
|
||||
|
||||
Here are some of the predefined validation attributes:
|
||||
* `[ValidateNever]`: ValidateNeverAttribute Indicates that a property or parameter should be excluded from validation.
|
||||
* `[CreditCard]`: Checks that the property has a credit card format. Requires additional jQuery validation methods.
|
||||
* `[Compare]`: Validates that two properties of a model match.
|
||||
* `[EmailAddress]`: Checks that the property has an email format.
|
||||
* `[Phone]`: Checks that the property has a phone number format.
|
||||
* `[Range]`: Checks that the property value is within a specified range.
|
||||
* `[RegularExpression]`: Validates that the property value matches a specified regular expression.
|
||||
* `[Required]`: Checks that the field is not null. For more information on the behavior of this attribute, see [Required] attribute.
|
||||
* `[StringLength]`: Validates that a property value of type String does not exceed a specified length limit.
|
||||
* `[Url]`: Checks that the property has a URL format.
|
||||
* `[Remote]`: Validates input on the client by calling an action method on the server. For more information on the behavior of this attribute, see [Remote] attribute.
|
||||
|
||||
You can find the full list of validation attributes in the [System.ComponentModel.DataAnnotations](https://docs.microsoft.com/fr-fr/dotnet/api/system.componentmodel.dataannotations) namespace.
|
||||
|
||||
### Error Messages
|
||||
|
||||
Validation attributes allow you to specify the error message to display for invalid input. For instance :
|
||||
|
||||
```csharp
|
||||
[StringLength(8, ErrorMessage = "Name length can't be more than 8.")]
|
||||
```
|
||||
|
||||
Internally the attributes call `String.Format` with a placeholder for the field name and sometimes other placeholders. For instance :
|
||||
|
||||
```csharp
|
||||
[StringLength(8, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 6)]
|
||||
```
|
||||
|
||||
Applied to a `Name` property, the error message created by the previous code would be "Name length must be between 6 and 8".
|
||||
|
||||
To find out what parameters are passed to `String.Format` for the error message of a particular attribute, see the [DataAnnotations source code](https://github.com/dotnet/runtime/tree/main/src /libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations).
|
||||
|
||||
### Custom attributes
|
||||
|
||||
For scenarios not handled by the predefined validation attributes, you can create custom validation attributes. Create a class that inherits from ValidationAttribute and override the IsValid method.
|
||||
|
||||
The `IsValid` method accepts an object named value, which is the input to validate. An overload also accepts a `ValidationContext` object, which provides additional information such as the model instance created by the model binding.
|
||||
|
||||
The following example checks that the release date of a movie belonging to the Classic genre is not later than a specified year. The `[ClassicMovie]` attribute:
|
||||
* Runs only on the server.
|
||||
* For classic films, validate the publication date:
|
||||
|
||||
```csharp
|
||||
public class ClassicMovieAttribute : ValidationAttribute
|
||||
{
|
||||
public ClassicMovieAttribute(int year)
|
||||
{
|
||||
Year = year;
|
||||
}
|
||||
|
||||
public int Year { get; }
|
||||
|
||||
public string GetErrorMessage() =>
|
||||
$"Classic movies must have a release year no later than {Year}.";
|
||||
|
||||
protected override ValidationResult IsValid(object value,
|
||||
ValidationContext validationContext)
|
||||
{
|
||||
var movie = (Movie)validationContext.ObjectInstance;
|
||||
var releaseYear = ((DateTime)value).Year;
|
||||
|
||||
if (movie.Genre == Genre.Classic && releaseYear > Year)
|
||||
{
|
||||
return new ValidationResult(GetErrorMessage());
|
||||
}
|
||||
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `movie` variable in the previous example represents a `Movie` object that contains the form submission data. When validation fails, a `ValidationResult` with an error message is returned.
|
||||
---
|
||||
sidebar_position: 5
|
||||
title: Creation of the add model
|
||||
---
|
||||
|
||||
## Add model
|
||||
|
||||
In order to add an element we will create an object representing our item.
|
||||
|
||||
For this in create a new class `Models/ItemModel.cs`, this class will include all the information of our API object.
|
||||
|
||||
We will also add a property so that the user accepts the conditions of addition.
|
||||
|
||||
Similarly, annotations will be present to validate the fields of our forms.
|
||||
|
||||
```csharp title="Models/ItemModel.cs"
|
||||
public class ItemModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(50, ErrorMessage = "The display name must not exceed 50 characters.")]
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(50, ErrorMessage = "The name must not exceed 50 characters.")]
|
||||
[RegularExpression(@"^[a-z''-'\s]{1,50}$", ErrorMessage = "Only lowercase characters are accepted.")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[Range(1, 64)]
|
||||
public int StackSize { get; set; }
|
||||
|
||||
[Required]
|
||||
[Range(1, 125)]
|
||||
public int MaxDurability { get; set; }
|
||||
|
||||
public List<string> EnchantCategories { get; set; }
|
||||
|
||||
public List<string> RepairWith { get; set; }
|
||||
|
||||
[Required]
|
||||
[Range(typeof(bool), "true", "true", ErrorMessage = "You must agree to the terms.")]
|
||||
public bool AcceptCondition { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "The image of the item is mandatory!")]
|
||||
public byte[] ImageContent { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
## Concept: Data Annotation
|
||||
|
||||
### Validation attributes
|
||||
|
||||
Validation attributes allow you to specify validation rules for model properties.
|
||||
|
||||
The following example shows a model class that is annotated with validation attributes.
|
||||
The `[ClassicMovie]` attribute is a custom validation attribute, and the others are predefined.
|
||||
|
||||
```csharp
|
||||
public class Movie
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Title { get; set; }
|
||||
|
||||
[ClassicMovie(1960)]
|
||||
[DataType(DataType.Date)]
|
||||
[Display(Name = "Release Date")]
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(1000)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Range(0, 999.99)]
|
||||
public decimal Price { get; set; }
|
||||
|
||||
public Genre Genre { get; set; }
|
||||
|
||||
public bool Preorder { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
### Attributs prédéfinis
|
||||
|
||||
Here are some of the predefined validation attributes:
|
||||
* `[ValidateNever]`: ValidateNeverAttribute Indicates that a property or parameter should be excluded from validation.
|
||||
* `[CreditCard]`: Checks that the property has a credit card format. Requires additional jQuery validation methods.
|
||||
* `[Compare]`: Validates that two properties of a model match.
|
||||
* `[EmailAddress]`: Checks that the property has an email format.
|
||||
* `[Phone]`: Checks that the property has a phone number format.
|
||||
* `[Range]`: Checks that the property value is within a specified range.
|
||||
* `[RegularExpression]`: Validates that the property value matches a specified regular expression.
|
||||
* `[Required]`: Checks that the field is not null. For more information on the behavior of this attribute, see [Required] attribute.
|
||||
* `[StringLength]`: Validates that a property value of type String does not exceed a specified length limit.
|
||||
* `[Url]`: Checks that the property has a URL format.
|
||||
* `[Remote]`: Validates input on the client by calling an action method on the server. For more information on the behavior of this attribute, see [Remote] attribute.
|
||||
|
||||
You can find the full list of validation attributes in the [System.ComponentModel.DataAnnotations](https://docs.microsoft.com/fr-fr/dotnet/api/system.componentmodel.dataannotations) namespace.
|
||||
|
||||
### Error Messages
|
||||
|
||||
Validation attributes allow you to specify the error message to display for invalid input. For instance :
|
||||
|
||||
```csharp
|
||||
[StringLength(8, ErrorMessage = "Name length can't be more than 8.")]
|
||||
```
|
||||
|
||||
Internally the attributes call `String.Format` with a placeholder for the field name and sometimes other placeholders. For instance :
|
||||
|
||||
```csharp
|
||||
[StringLength(8, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 6)]
|
||||
```
|
||||
|
||||
Applied to a `Name` property, the error message created by the previous code would be "Name length must be between 6 and 8".
|
||||
|
||||
To find out what parameters are passed to `String.Format` for the error message of a particular attribute, see the [DataAnnotations source code](https://github.com/dotnet/runtime/tree/main/src /libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations).
|
||||
|
||||
### Custom attributes
|
||||
|
||||
For scenarios not handled by the predefined validation attributes, you can create custom validation attributes. Create a class that inherits from ValidationAttribute and override the IsValid method.
|
||||
|
||||
The `IsValid` method accepts an object named value, which is the input to validate. An overload also accepts a `ValidationContext` object, which provides additional information such as the model instance created by the model binding.
|
||||
|
||||
The following example checks that the release date of a movie belonging to the Classic genre is not later than a specified year. The `[ClassicMovie]` attribute:
|
||||
* Runs only on the server.
|
||||
* For classic films, validate the publication date:
|
||||
|
||||
```csharp
|
||||
public class ClassicMovieAttribute : ValidationAttribute
|
||||
{
|
||||
public ClassicMovieAttribute(int year)
|
||||
{
|
||||
Year = year;
|
||||
}
|
||||
|
||||
public int Year { get; }
|
||||
|
||||
public string GetErrorMessage() =>
|
||||
$"Classic movies must have a release year no later than {Year}.";
|
||||
|
||||
protected override ValidationResult IsValid(object value,
|
||||
ValidationContext validationContext)
|
||||
{
|
||||
var movie = (Movie)validationContext.ObjectInstance;
|
||||
var releaseYear = ((DateTime)value).Year;
|
||||
|
||||
if (movie.Genre == Genre.Classic && releaseYear > Year)
|
||||
{
|
||||
return new ValidationResult(GetErrorMessage());
|
||||
}
|
||||
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `movie` variable in the previous example represents a `Movie` object that contains the form submission data. When validation fails, a `ValidationResult` with an error message is returned.
|
||||
|
@ -1,365 +1,365 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
title: Creation of page editor
|
||||
---
|
||||
|
||||
## Creation of the page
|
||||
|
||||
As before, create a new page which will be named `Edit.razor` and the partial class `Edit.razor.cs`.
|
||||
|
||||
## Final source code
|
||||
|
||||
```cshtml title="Pages/Edit.razor"
|
||||
<h3>Edit</h3>
|
||||
|
||||
```
|
||||
|
||||
```csharp title="Pages/Edit.razor.cs"
|
||||
public partial class Edit
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
## Set page url
|
||||
|
||||
We are going to define the url of our page by specifying that we want our identifier.
|
||||
|
||||
Open the `Pages/Edit.razor` file and add the highlighted edits as follows:
|
||||
|
||||
```cshtml title="Pages/Edit.razor"
|
||||
// highlight-next-line
|
||||
@page "/edit/{Id:int}"
|
||||
|
||||
<h3>Edit</h3>
|
||||
|
||||
```
|
||||
|
||||
## Pass a parameter
|
||||
|
||||
We passed in the url the id of our item to edit, now we are going to retrieve it in a `Parameter` in order to be able to use it in our code.
|
||||
|
||||
Open the `Pages/Edit.razor.cs` file and add the highlighted edits as follows:
|
||||
|
||||
```cshtml title="Pages/Edit.razor.cs"
|
||||
public partial class Edit
|
||||
{
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## View Parameter
|
||||
|
||||
In order to verify the passage of our identifier we will display it.
|
||||
|
||||
Open the `Pages/Edit.razor` file and add the highlighted edits as follows:
|
||||
|
||||
```cshtml title="Pages/Edit.razor"
|
||||
@page "/edit/{Id:int}"
|
||||
|
||||
<h3>Edit</h3>
|
||||
|
||||
// highlight-next-line
|
||||
<div>My paremeter: @Id</div>
|
||||
|
||||
```
|
||||
|
||||
## Concept: URL parameters
|
||||
|
||||
### Route settings
|
||||
|
||||
The router uses routing parameters to populate corresponding component parameters with the same name.
|
||||
Route parameter names are case insensitive. In the following example, the `text` parameter assigns the value of the road segment to the component's `Text` property.
|
||||
When a request is made for `/RouteParameter/amazing`, the `<h1>` tag content is rendered as `Blazor is amazing!`.
|
||||
|
||||
```cshtml title="Pages/RouteParameter.razor"
|
||||
@page "/RouteParameter/{text}"
|
||||
|
||||
<h1>Blazor is @Text!</h1>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string? Text { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
Optional parameters are supported.
|
||||
In the following example, the optional `text` parameter assigns the value of the route segment to the component's `Text` property. If the segment is not present, the value of `Text` is set to `fantastic`.
|
||||
|
||||
```cshtml title="Pages/RouteParameter.razor"
|
||||
@page "/RouteParameter/{text?}"
|
||||
|
||||
<h1>Blazor is @Text!</h1>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string? Text { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Text = Text ?? "fantastic";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use `OnParametersSet OnInitialized{Async}` instead to allow navigation to the same component with a different optional parameter value.
|
||||
Based on the previous example, use `OnParametersSet` when the user needs to navigate from `/RouteParameter` to `/RouteParameter/amazing` or from `/RouteParameter/amazing` to `/RouteParameter`:
|
||||
|
||||
```html
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
Text = Text ?? "fantastic";
|
||||
}
|
||||
```
|
||||
|
||||
### Route Constraints
|
||||
|
||||
A route constraint applies type matching on a route segment to a component.
|
||||
|
||||
In the following example, the route to the `User` component matches only if:
|
||||
* A routing `Id` segment is present in the request URL.
|
||||
* The `Id` segment is an integer type ( `int` ).
|
||||
|
||||
```cshtml title="Pages/User.razor"
|
||||
@page "/user/{Id:int}"
|
||||
|
||||
<h1>User Id: @Id</h1>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
The route constraints shown in the following table are available.
|
||||
For more information about route constraints that correspond to the indifferent culture, see the disclaimer below the table.
|
||||
|
||||
| Constraint | Example | Matching examples | Invariant culture correspondence
|
||||
| ---- | ---- | ---- | ----
|
||||
| `bool` | `{active:bool}` | `true`, FALSE | No
|
||||
| `datetime` | `{dob:datetime}` | `2016-12-31`, `2016-12-31 7:32pm` | Yes
|
||||
| `decimal` | `{price:decimal}` | `49.99`, `-1,000.01` | Yes
|
||||
| `double` | `{weight:double}` | `1.234`, `-1,001.01e8` | Yes
|
||||
| `float` | `{weight:float}` | `1.234, -1`,`001.01e8` | Yes
|
||||
| `guid` | `{id:guid}` | `CD2C1638-1638-72D5-1638-DEADBEEF1638`, `{CD2C1638-1638-72D5-1638-DEADBEEF1638}` | No
|
||||
| `int` | `{id:int}` | `123456789`, `-123456789` | Yes
|
||||
| `long` | `{ticks:long}` | `123456789`, `-123456789` | Yes
|
||||
|
||||
:::caution
|
||||
Routing constraints that check that the URL can be converted to a CLR type (like `int` or `DateTime`) always use the invariant culture. these constraints assume that the URL is not localizable.
|
||||
:::
|
||||
|
||||
Route constraints also work with optional parameters. In the following example, `Id` is required, but `Option` is an optional boolean route parameter.
|
||||
|
||||
```cshtml title="Pages/User.razor"
|
||||
@page "/user/{Id:int}/{Option:bool?}"
|
||||
|
||||
<p>
|
||||
Id: @Id
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Option: @Option
|
||||
</p>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Option { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
## Concept: Component Parameters
|
||||
|
||||
Component parameters pass data to components and are set using Public C# Properties on the component class with the `[Parameter]` attribute.
|
||||
|
||||
In the following example, a built-in reference type ( `System.String` ) and a user-defined reference type ( `PanelBody` ) are passed as component parameters.
|
||||
|
||||
```csharp title="PanelBody.cs"
|
||||
public class PanelBody
|
||||
{
|
||||
public string? Text { get; set; }
|
||||
public string? Style { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
```cshtml title="Shared/ParameterChild.razor"
|
||||
<div class="card w-25" style="margin-bottom:15px">
|
||||
<div class="card-header font-weight-bold">@Title</div>
|
||||
<div class="card-body" style="font-style:@Body.Style">
|
||||
@Body.Text
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string Title { get; set; } = "Set By Child";
|
||||
|
||||
[Parameter]
|
||||
public PanelBody Body { get; set; } =
|
||||
new()
|
||||
{
|
||||
Text = "Set by child.",
|
||||
Style = "normal"
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
:::caution
|
||||
Providing initial values for component parameters is supported, but does not create a component that writes to its own parameters after the component is first rendered.
|
||||
:::
|
||||
|
||||
|
||||
The `Title` & `Body` component and `ParameterChild` component parameters are defined by arguments in the HTML tag that renders the component instance.
|
||||
The following `ParameterParent` component renders two `ParameterChild` components:
|
||||
* The first `ParameterChild` component is rendered without providing any parameter arguments.
|
||||
* The second `ParameterChild` component receives values for `Title` and `Body` from the `ParameterParent` component, which uses an explicit C# expression to set the values for the properties of `PanelBody`.
|
||||
|
||||
```cshtml title="Pages/ParameterParent.razor"
|
||||
@page "/parameter-parent"
|
||||
|
||||
<h1>Child component (without attribute values)</h1>
|
||||
|
||||
<ParameterChild />
|
||||
|
||||
<h1>Child component (with attribute values)</h1>
|
||||
|
||||
<ParameterChild Title="Set by Parent" Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
|
||||
```
|
||||
|
||||
The following rendered HTML markup of the `ParameterParent` component shows default `ParameterChild` values for components when the `ParameterParent` component does not provide component parameter values.
|
||||
When the `ParameterParent` component provides component parameter values, they override the component's default `ParameterChild` values.
|
||||
|
||||
:::note
|
||||
For clarity, rendered CSS style classes are not shown in the following rendered HTML markup.
|
||||
:::
|
||||
|
||||
```html
|
||||
<h1>Child component (without attribute values)</h1>
|
||||
|
||||
<div>
|
||||
<div>Set By Child</div>
|
||||
<div>Set by child.</div>
|
||||
</div>
|
||||
|
||||
<h1>Child component (with attribute values)</h1>
|
||||
|
||||
<div>
|
||||
<div>Set by Parent</div>
|
||||
<div>Set by parent.</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
Assign a C# field, property, or result of a method to a component parameter as an HTML attribute value using the `@` symbol.
|
||||
The following `ParameterParent2` component displays four instances of the preceding `ParameterChild` component and sets their parameter `Title` values to:
|
||||
* Value of the `title` field.
|
||||
* Result of C# `GetTitle` method.
|
||||
* Current local date in long format with `ToLongDateString`, which uses an implicit C# expression.
|
||||
* `panelData` Property of the `Title` object.
|
||||
|
||||
```cshtml title="Pages/ParameterParent2.razor"
|
||||
@page "/parameter-parent-2"
|
||||
|
||||
<ParameterChild Title="@title" />
|
||||
|
||||
<ParameterChild Title="@GetTitle()" />
|
||||
|
||||
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
|
||||
|
||||
<ParameterChild Title="@panelData.Title" />
|
||||
|
||||
@code {
|
||||
private string title = "From Parent field";
|
||||
private PanelData panelData = new();
|
||||
|
||||
private string GetTitle()
|
||||
{
|
||||
return "From Parent method";
|
||||
}
|
||||
|
||||
private class PanelData
|
||||
{
|
||||
public string Title { get; set; } = "From Parent object";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
When assigning a C# member to a component parameter, prefix the member with the `@` symbol and never prefix the parameter's HTML attribute.
|
||||
|
||||
Correct use:
|
||||
```html
|
||||
<ParameterChild Title="@title" />
|
||||
```
|
||||
|
||||
Wrong:
|
||||
```html
|
||||
<ParameterChild @Title="title" />
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Using an explicit Razor expression to concatenate text with an expression result for assignment to a parameter is not supported.
|
||||
|
||||
The following example attempts to concatenate the text "Set by" with the property value of an object. The following Razor syntax is not supported:
|
||||
|
||||
```html
|
||||
<ParameterChild Title="Set by @(panelData.Title)" />
|
||||
```
|
||||
|
||||
The code in the previous example generates a Compiler Error when building the application:
|
||||
|
||||
```
|
||||
Les attributs de composant ne prennent pas en charge le contenu complexe (mixte C# et balisage).
|
||||
```
|
||||
|
||||
To support assigning a compound value, use a method, field, or property. The following example performs the concatenation of "`Set by`" and the property value of an object in the C# `GetTitle` method:
|
||||
|
||||
```cshtml title="Pages/ParameterParent3.razor"
|
||||
@page "/parameter-parent-3"
|
||||
|
||||
<ParameterChild Title="@GetTitle()" />
|
||||
|
||||
@code {
|
||||
private PanelData panelData = new();
|
||||
|
||||
private string GetTitle() => $"Set by {panelData.Title}";
|
||||
|
||||
private class PanelData
|
||||
{
|
||||
public string Title { get; set; } = "Parent";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Component parameters must be declared as Automatic Properties, which means they must not contain custom logic in their `get` or `set` accessors.
|
||||
For example, the following `StartData` property is an automatic property:
|
||||
|
||||
```csharp
|
||||
[Parameter]
|
||||
public DateTime StartData { get; set; }
|
||||
```
|
||||
|
||||
Do not put custom logic in the `get` or `set` accessor, as component parameters are purely for use as a channel from a parent component to pass information to a child component.
|
||||
If a `set` accessor of a child component property contains logic that causes the parent component to be re-rendered, the results of an infinite render loop.
|
||||
|
||||
To transform a received parameter value:
|
||||
|
||||
* Leave the parameter property as auto property to represent the raw data provided.
|
||||
* Create another property or method to provide the transformed data based on the parameter property.
|
||||
|
||||
Override `OnParametersSetAsync` to transform a received parameter each time new data is received.
|
||||
|
||||
Writing an initial value to a component parameter is supported because initial value assignments don't interfere with automatic component Blazor rendering.
|
||||
The following assignment of the current locale `DateTime` with `DateTime.Now` to `StartData` is valid syntax in a component:
|
||||
|
||||
```csharp
|
||||
[Parameter]
|
||||
public DateTime StartData { get; set; } = DateTime.Now;
|
||||
```
|
||||
|
||||
After the initial assignment of `DateTime.Now`, do not assign a value to `StartData` in code.
|
||||
---
|
||||
sidebar_position: 4
|
||||
title: Creation of page editor
|
||||
---
|
||||
|
||||
## Creation of the page
|
||||
|
||||
As before, create a new page which will be named `Edit.razor` and the partial class `Edit.razor.cs`.
|
||||
|
||||
## Final source code
|
||||
|
||||
```cshtml title="Pages/Edit.razor"
|
||||
<h3>Edit</h3>
|
||||
|
||||
```
|
||||
|
||||
```csharp title="Pages/Edit.razor.cs"
|
||||
public partial class Edit
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
## Set page url
|
||||
|
||||
We are going to define the url of our page by specifying that we want our identifier.
|
||||
|
||||
Open the `Pages/Edit.razor` file and add the highlighted edits as follows:
|
||||
|
||||
```cshtml title="Pages/Edit.razor"
|
||||
// highlight-next-line
|
||||
@page "/edit/{Id:int}"
|
||||
|
||||
<h3>Edit</h3>
|
||||
|
||||
```
|
||||
|
||||
## Pass a parameter
|
||||
|
||||
We passed in the url the id of our item to edit, now we are going to retrieve it in a `Parameter` in order to be able to use it in our code.
|
||||
|
||||
Open the `Pages/Edit.razor.cs` file and add the highlighted edits as follows:
|
||||
|
||||
```cshtml title="Pages/Edit.razor.cs"
|
||||
public partial class Edit
|
||||
{
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## View Parameter
|
||||
|
||||
In order to verify the passage of our identifier we will display it.
|
||||
|
||||
Open the `Pages/Edit.razor` file and add the highlighted edits as follows:
|
||||
|
||||
```cshtml title="Pages/Edit.razor"
|
||||
@page "/edit/{Id:int}"
|
||||
|
||||
<h3>Edit</h3>
|
||||
|
||||
// highlight-next-line
|
||||
<div>My parameter: @Id</div>
|
||||
|
||||
```
|
||||
|
||||
## Concept: URL parameters
|
||||
|
||||
### Route settings
|
||||
|
||||
The router uses routing parameters to populate corresponding component parameters with the same name.
|
||||
Route parameter names are case insensitive. In the following example, the `text` parameter assigns the value of the road segment to the component's `Text` property.
|
||||
When a request is made for `/RouteParameter/amazing`, the `<h1>` tag content is rendered as `Blazor is amazing!`.
|
||||
|
||||
```cshtml title="Pages/RouteParameter.razor"
|
||||
@page "/RouteParameter/{text}"
|
||||
|
||||
<h1>Blazor is @Text!</h1>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string? Text { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
Optional parameters are supported.
|
||||
In the following example, the optional `text` parameter assigns the value of the route segment to the component's `Text` property. If the segment is not present, the value of `Text` is set to `fantastic`.
|
||||
|
||||
```cshtml title="Pages/RouteParameter.razor"
|
||||
@page "/RouteParameter/{text?}"
|
||||
|
||||
<h1>Blazor is @Text!</h1>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string? Text { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Text = Text ?? "fantastic";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use `OnParametersSet OnInitialized{Async}` instead to allow navigation to the same component with a different optional parameter value.
|
||||
Based on the previous example, use `OnParametersSet` when the user needs to navigate from `/RouteParameter` to `/RouteParameter/amazing` or from `/RouteParameter/amazing` to `/RouteParameter`:
|
||||
|
||||
```html
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
Text = Text ?? "fantastic";
|
||||
}
|
||||
```
|
||||
|
||||
### Route Constraints
|
||||
|
||||
A route constraint applies type matching on a route segment to a component.
|
||||
|
||||
In the following example, the route to the `User` component matches only if:
|
||||
* A routing `Id` segment is present in the request URL.
|
||||
* The `Id` segment is an integer type ( `int` ).
|
||||
|
||||
```cshtml title="Pages/User.razor"
|
||||
@page "/user/{Id:int}"
|
||||
|
||||
<h1>User Id: @Id</h1>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
The route constraints shown in the following table are available.
|
||||
For more information about route constraints that correspond to the indifferent culture, see the disclaimer below the table.
|
||||
|
||||
| Constraint | Example | Matching examples | Invariant culture correspondence
|
||||
| ---- | ---- | ---- | ----
|
||||
| `bool` | `{active:bool}` | `true`, FALSE | No
|
||||
| `datetime` | `{dob:datetime}` | `2016-12-31`, `2016-12-31 7:32pm` | Yes
|
||||
| `decimal` | `{price:decimal}` | `49.99`, `-1,000.01` | Yes
|
||||
| `double` | `{weight:double}` | `1.234`, `-1,001.01e8` | Yes
|
||||
| `float` | `{weight:float}` | `1.234, -1`,`001.01e8` | Yes
|
||||
| `guid` | `{id:guid}` | `CD2C1638-1638-72D5-1638-DEADBEEF1638`, `{CD2C1638-1638-72D5-1638-DEADBEEF1638}` | No
|
||||
| `int` | `{id:int}` | `123456789`, `-123456789` | Yes
|
||||
| `long` | `{ticks:long}` | `123456789`, `-123456789` | Yes
|
||||
|
||||
:::caution
|
||||
Routing constraints that check that the URL can be converted to a CLR type (like `int` or `DateTime`) always use the invariant culture. these constraints assume that the URL is not localizable.
|
||||
:::
|
||||
|
||||
Route constraints also work with optional parameters. In the following example, `Id` is required, but `Option` is an optional boolean route parameter.
|
||||
|
||||
```cshtml title="Pages/User.razor"
|
||||
@page "/user/{Id:int}/{Option:bool?}"
|
||||
|
||||
<p>
|
||||
Id: @Id
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Option: @Option
|
||||
</p>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Option { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
## Concept: Component Parameters
|
||||
|
||||
Component parameters pass data to components and are set using Public C# Properties on the component class with the `[Parameter]` attribute.
|
||||
|
||||
In the following example, a built-in reference type ( `System.String` ) and a user-defined reference type ( `PanelBody` ) are passed as component parameters.
|
||||
|
||||
```csharp title="PanelBody.cs"
|
||||
public class PanelBody
|
||||
{
|
||||
public string? Text { get; set; }
|
||||
public string? Style { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
```cshtml title="Shared/ParameterChild.razor"
|
||||
<div class="card w-25" style="margin-bottom:15px">
|
||||
<div class="card-header font-weight-bold">@Title</div>
|
||||
<div class="card-body" style="font-style:@Body.Style">
|
||||
@Body.Text
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string Title { get; set; } = "Set By Child";
|
||||
|
||||
[Parameter]
|
||||
public PanelBody Body { get; set; } =
|
||||
new()
|
||||
{
|
||||
Text = "Set by child.",
|
||||
Style = "normal"
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
:::caution
|
||||
Providing initial values for component parameters is supported, but does not create a component that writes to its own parameters after the component is first rendered.
|
||||
:::
|
||||
|
||||
|
||||
The `Title` & `Body` component and `ParameterChild` component parameters are defined by arguments in the HTML tag that renders the component instance.
|
||||
The following `ParameterParent` component renders two `ParameterChild` components:
|
||||
* The first `ParameterChild` component is rendered without providing any parameter arguments.
|
||||
* The second `ParameterChild` component receives values for `Title` and `Body` from the `ParameterParent` component, which uses an explicit C# expression to set the values for the properties of `PanelBody`.
|
||||
|
||||
```cshtml title="Pages/ParameterParent.razor"
|
||||
@page "/parameter-parent"
|
||||
|
||||
<h1>Child component (without attribute values)</h1>
|
||||
|
||||
<ParameterChild />
|
||||
|
||||
<h1>Child component (with attribute values)</h1>
|
||||
|
||||
<ParameterChild Title="Set by Parent" Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
|
||||
```
|
||||
|
||||
The following rendered HTML markup of the `ParameterParent` component shows default `ParameterChild` values for components when the `ParameterParent` component does not provide component parameter values.
|
||||
When the `ParameterParent` component provides component parameter values, they override the component's default `ParameterChild` values.
|
||||
|
||||
:::note
|
||||
For clarity, rendered CSS style classes are not shown in the following rendered HTML markup.
|
||||
:::
|
||||
|
||||
```html
|
||||
<h1>Child component (without attribute values)</h1>
|
||||
|
||||
<div>
|
||||
<div>Set By Child</div>
|
||||
<div>Set by child.</div>
|
||||
</div>
|
||||
|
||||
<h1>Child component (with attribute values)</h1>
|
||||
|
||||
<div>
|
||||
<div>Set by Parent</div>
|
||||
<div>Set by parent.</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
Assign a C# field, property, or result of a method to a component parameter as an HTML attribute value using the `@` symbol.
|
||||
The following `ParameterParent2` component displays four instances of the preceding `ParameterChild` component and sets their parameter `Title` values to:
|
||||
* Value of the `title` field.
|
||||
* Result of C# `GetTitle` method.
|
||||
* Current local date in long format with `ToLongDateString`, which uses an implicit C# expression.
|
||||
* `panelData` Property of the `Title` object.
|
||||
|
||||
```cshtml title="Pages/ParameterParent2.razor"
|
||||
@page "/parameter-parent-2"
|
||||
|
||||
<ParameterChild Title="@title" />
|
||||
|
||||
<ParameterChild Title="@GetTitle()" />
|
||||
|
||||
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
|
||||
|
||||
<ParameterChild Title="@panelData.Title" />
|
||||
|
||||
@code {
|
||||
private string title = "From Parent field";
|
||||
private PanelData panelData = new();
|
||||
|
||||
private string GetTitle()
|
||||
{
|
||||
return "From Parent method";
|
||||
}
|
||||
|
||||
private class PanelData
|
||||
{
|
||||
public string Title { get; set; } = "From Parent object";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
When assigning a C# member to a component parameter, prefix the member with the `@` symbol and never prefix the parameter's HTML attribute.
|
||||
|
||||
Correct use:
|
||||
```html
|
||||
<ParameterChild Title="@title" />
|
||||
```
|
||||
|
||||
Wrong:
|
||||
```html
|
||||
<ParameterChild @Title="title" />
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Using an explicit Razor expression to concatenate text with an expression result for assignment to a parameter is not supported.
|
||||
|
||||
The following example attempts to concatenate the text "Set by" with the property value of an object. The following Razor syntax is not supported:
|
||||
|
||||
```html
|
||||
<ParameterChild Title="Set by @(panelData.Title)" />
|
||||
```
|
||||
|
||||
The code in the previous example generates a Compiler Error when building the application:
|
||||
|
||||
```
|
||||
Les attributs de composant ne prennent pas en charge le contenu complexe (mixte C# et balisage).
|
||||
```
|
||||
|
||||
To support assigning a compound value, use a method, field, or property. The following example performs the concatenation of "`Set by`" and the property value of an object in the C# `GetTitle` method:
|
||||
|
||||
```cshtml title="Pages/ParameterParent3.razor"
|
||||
@page "/parameter-parent-3"
|
||||
|
||||
<ParameterChild Title="@GetTitle()" />
|
||||
|
||||
@code {
|
||||
private PanelData panelData = new();
|
||||
|
||||
private string GetTitle() => $"Set by {panelData.Title}";
|
||||
|
||||
private class PanelData
|
||||
{
|
||||
public string Title { get; set; } = "Parent";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Component parameters must be declared as Automatic Properties, which means they must not contain custom logic in their `get` or `set` accessors.
|
||||
For example, the following `StartData` property is an automatic property:
|
||||
|
||||
```csharp
|
||||
[Parameter]
|
||||
public DateTime StartData { get; set; }
|
||||
```
|
||||
|
||||
Do not put custom logic in the `get` or `set` accessor, as component parameters are purely for use as a channel from a parent component to pass information to a child component.
|
||||
If a `set` accessor of a child component property contains logic that causes the parent component to be re-rendered, the results of an infinite render loop.
|
||||
|
||||
To transform a received parameter value:
|
||||
|
||||
* Leave the parameter property as auto property to represent the raw data provided.
|
||||
* Create another property or method to provide the transformed data based on the parameter property.
|
||||
|
||||
Override `OnParametersSetAsync` to transform a received parameter each time new data is received.
|
||||
|
||||
Writing an initial value to a component parameter is supported because initial value assignments don't interfere with automatic component Blazor rendering.
|
||||
The following assignment of the current locale `DateTime` with `DateTime.Now` to `StartData` is valid syntax in a component:
|
||||
|
||||
```csharp
|
||||
[Parameter]
|
||||
public DateTime StartData { get; set; } = DateTime.Now;
|
||||
```
|
||||
|
||||
After the initial assignment of `DateTime.Now`, do not assign a value to `StartData` in code.
|
||||
|
@ -1,24 +1,24 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
title: Description du composant
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Afin de mieux comprendre notre composant complexe, nous allons en premier faire une petite description de son contenu et du comportement attendu par celui-ci.
|
||||
|
||||
Le but de ce composant et de permettre de tester des recettes, pour cela nous devons avoir sur la gauche un tableu contenant la liste des éléments disponible pour notre recette.
|
||||
|
||||
A droite nous devons trouver les emplacements qui contiendront nos éléments de recette, une fois notre recette valide, un dernier élément sera affiché sous nos emplacements avec le résulat de la recette.
|
||||
|
||||
Une liste en dessous contiendra l'ensemble des actions rélisées par l'utilisateur et sera géré en Javascript.
|
||||
|
||||
## Mockup
|
||||
|
||||
Pour une meilleur visualisation de notre composant, un mockup peut être réalisé afin de mieux se rendre compte du final.
|
||||
|
||||
Pour cela nous pouvons utiliser le site https://wireframe.cc/.
|
||||
|
||||
Le résulat du mockup est :
|
||||
|
||||
---
|
||||
sidebar_position: 3
|
||||
title: Description du composant
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Afin de mieux comprendre notre composant complexe, nous allons en premier faire une petite description de son contenu et du comportement attendu par celui-ci.
|
||||
|
||||
Le but de ce composant et de permettre de tester des recettes, pour cela nous devons avoir sur la gauche un tableau contenant la liste des éléments disponible pour notre recette.
|
||||
|
||||
A droite nous devons trouver les emplacements qui contiendront nos éléments de recette, une fois notre recette valide, un dernier élément sera affiché sous nos emplacements avec le résulat de la recette.
|
||||
|
||||
Une liste en dessous contiendra l'ensemble des actions réalisées par l'utilisateur et sera géré en Javascript.
|
||||
|
||||
## Mockup
|
||||
|
||||
Pour une meilleur visualisation de notre composant, un mockup peut être réalisé afin de mieux se rendre compte du final.
|
||||
|
||||
Pour cela nous pouvons utiliser le site https://wireframe.cc/.
|
||||
|
||||
Le résulat du mockup est :
|
||||
|
||||

|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue