---
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.
