Parte 8 della serie di esercitazioni sulle Razor pagine

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione ASP.NET Core 8.0 di questo articolo.

Di Rick Anderson

In questa sezione la logica di convalida viene aggiunta al modello Movie. Le regole di convalida vengono applicate ogni volta che un utente crea o modifica un film.

Convalida

Un concetto di base dello sviluppo del software si chiama DRY ("Don't Repeat Yourself", Non ripeterti). Razor Pages incoraggia lo sviluppo in cui la funzionalità viene specificata una sola volta e viene riflessa in tutta l'app. DRY contribuisce a:

  • Ridurre la quantità di codice in un'app.
  • Rendere il codice meno soggetto ad errori e più facile da testare e gestire.

Il supporto di convalida fornito da Razor Pages ed Entity Framework è un buon esempio del principio DRY:

  • Le regole di convalida vengono specificate in modo dichiarativo in un'unica posizione, nella classe del modello.
  • Le regole vengono applicate ovunque nell'app.

Aggiungere regole di convalida al modello movie

Lo System.ComponentModel.DataAnnotations spazio dei nomi fornisce:

  • Set di attributi di convalida predefiniti applicati in modo dichiarativo a una classe o a una proprietà.
  • La formattazione di attributi come [DataType] questo è utile per la formattazione e non fornisce alcuna convalida.

Aggiornare la classe Movie per poter sfruttare gli attributi di convalida [Required], [StringLength], [RegularExpression] e [Range] predefiniti.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models;

public class Movie
{
    public int Id { get; set; }

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string Title { get; set; } = string.Empty;

    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
    [Required]
    [StringLength(30)]
    public string Genre { get; set; } = string.Empty;

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
    [StringLength(5)]
    [Required]
    public string Rating { get; set; } = string.Empty;
}

Gli attributi di convalida specificano il comportamento da imporre nelle proprietà del modello a cui vengono applicati:

  • Gli attributi [Required] e [MinimumLength] indicano che una proprietà deve avere un valore. Nulla impedisce a un utente di immettere spazi vuoti per soddisfare questa convalida.

  • L'attributo [RegularExpression] viene usato per limitare i caratteri che possono essere inseriti. Nel codice precedente: Genre

    • Deve includere solo lettere.
    • La prima lettera deve essere maiuscola. Gli spazi vuoti sono consentiti, mentre i numeri e i caratteri speciali non sono consentiti.
  • RegularExpressionRating:

    • Richiede che il primo carattere sia una lettera maiuscola.
    • Consente i caratteri speciali e i numeri negli spazi successivi. "PG-13" è valido per una classificazione, ma non riesce per un oggetto Genre.
  • L'attributo [Range] vincola un valore all'interno di un intervallo specificato.

  • L'attributo [StringLength] può impostare una lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.

  • I tipi valore, ad esempio decimal, floatint, , DateTime, sono intrinsecamente necessari e non richiedono l'attributo [Required] .

Le regole di convalida precedenti vengono usate per la dimostrazione, non sono ottimali per un sistema di produzione. Ad esempio, il precedente impedisce l'immissione di un film con solo due caratteri e non consente caratteri speciali in Genre.

La presenza di regole di convalida applicate automaticamente da ASP.NET Core consente di:

  • Rendere l'app più affidabile.
  • Ridurre le probabilità di salvare dati non validi nel database.

Interfaccia utente degli errori di convalida nelle Razor pagine

Eseguire l'app e passare a Pages/Movies.

Selezionare il collegamento Crea nuovo. Completare il modulo con alcuni valori non validi. Quando la convalida del lato client jQuery rileva l'errore, viene visualizzato un messaggio di errore.

Movie view form with multiple jQuery client-side validation errors

Nota

È possibile che non si riesca a immettere virgole decimali nel campo. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .

Si noti come il modulo ha eseguito automaticamente il rendering di un messaggio di errore di convalida in ogni campo che contiene un valore non valido. Gli errori vengono applicati sia sul lato client, usando JavaScript che jQuery e lato server, quando un utente ha disabilitato JavaScript.

Un vantaggio significativo è che non c'era nessuna modifica del codice necessaria nelle pagine Create o Edit. Dopo l'applicazione delle annotazioni dei dati al modello, l'interfaccia utente di convalida è stata abilitata. Le Razor pagine create in questa esercitazione hanno selezionato automaticamente le regole di convalida, usando gli attributi di convalida per le proprietà della Movie classe modello. Convalida del test tramite la pagina Modifica, viene applicata la stessa convalida.

I dati del modulo non vengono registrati nel server fino a quando non sono presenti errori di convalida nel lato client. Verificare che i dati del modulo non siano stati registrati da uno o più degli approcci seguenti:

  • Inserire un punto di interruzione nel metodo OnPostAsync. Inviare il modulo selezionando Crea o Salva. Il punto di interruzione non viene mai raggiunto.
  • Usare lo Strumento Fiddler.
  • Usare gli strumenti di sviluppo del browser per monitorare il traffico di rete.

Convalida sul lato server

Quando JavaScript è disabilitato nel browser, l'invio del modulo con errori verrà inoltrato al server.

Facoltativo, convalida sul lato server del test:

  1. Disabilitare JavaScript nel browser. JavaScript può essere disabilitato usando gli strumenti di sviluppo del browser. Se JavaScript non può essere disabilitato nel browser, provare un altro browser.

  2. Impostare un punto di interruzione nel metodo OnPostAsync della pagina Crea o Modifica.

  3. Inviare un modulo con dati non validi.

  4. Verificare che lo stato del modello non sia valido:

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

In alternativa, disabilitare la convalida lato client nel server.

Il codice seguente illustra una parte dello scaffolding della Create.cshtml pagina in precedenza nell'esercitazione. Viene usato dalle pagine Crea e Modifica per:

  • Visualizzare il modulo iniziale.
  • Riprodurre di nuovo il modulo in caso di errore.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

L'helper tag di input usa gli attributi DataAnnotations e produce gli attributi HTML necessari per la convalida jQuery sul lato client. L'helper tag di convalida visualizza gli errori di convalida. Per altre informazioni, vedere Convalida.

Le pagine Create e Edit non dispongono di nessuna regola di convalida. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie. Queste regole di convalida vengono applicate automaticamente alle Razor pagine che modificano il Movie modello.

Quando la logica di convalida deve cambiare, avviene solo nel modello. La convalida viene applicata in modo coerente in tutta l'app, la logica di convalida viene definita in un'unica posizione. La convalida in un'unica posizione consente di mantenere il codice pulito e rende più semplice la gestione e l'aggiornamento.

Usare attributi DataType

Esaminare la classe Movie. Lo spazio dei nomi System.ComponentModel.DataAnnotations fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. L'attributo [DataType] viene applicato alle proprietà ReleaseDate e Price.

[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }

Gli [DataType] attributi forniscono:

  • Hint per il motore di visualizzazione per formattare i dati.
  • Fornisce attributi come <a> per l'URL e <a href="mailto:EmailAddress.com"> per la posta elettronica.

Usare l'attributo [RegularExpression] per convalidare il formato dei dati. L'attributo [DataType] viene usato per specificare un tipo di dati che è più specifico del tipo intrinseco del database. [DataType] gli attributi non sono attributi di convalida. Nell'app di esempio viene visualizzata solo la data, senza ora.

L'enumerazione DataType fornisce molti tipi di dati, ad esempio Date, TimePhoneNumber, Currency, EmailAddress, e altro ancora.

Attributi [DataType] :

  • Può abilitare l'app per fornire automaticamente funzionalità specifiche del tipo. Ad esempio, è possibile creare un collegamento mailto: per DataType.EmailAddress.
  • Può fornire un selettore DataType.Date di data nei browser che supportano HTML5.
  • Genera HTML 5 data-, pronunciato "trattino dati", attributi utilizzati dai browser HTML 5.
  • Non fornire alcuna convalida.

DataType.Date non specifica il formato della data visualizzata. Per impostazione predefinita, il campo dei dati viene visualizzato in base ai formati predefiniti per il valore CultureInfo del server.

L'annotazione dei dati [Column(TypeName = "decimal(18, 2)")] è necessaria per consentire a Entity Framework Core di eseguire correttamente il mapping di Price nella valuta del database. Per altre informazioni, vedere Tipi di dati.

L'attributo [DisplayFormat] viene usato per specificare in modo esplicito il formato della data:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

L'impostazione ApplyFormatInEditMode specifica che la formattazione verrà applicata quando viene visualizzato il valore per la modifica. Questo comportamento potrebbe non essere voluto per alcuni campi. Ad esempio, nei valori di valuta, il simbolo di valuta non è in genere desiderato nell'interfaccia utente di modifica.

L'attributo [DisplayFormat] può essere usato da solo, ma in genere è consigliabile usare l'attributo [DataType]. L'attributo [DataType] offre la semantica dei dati anziché specificarne il rendering in una schermata. L'attributo [DataType] offre i vantaggi seguenti che non sono disponibili con [DisplayFormat]:

  • Il browser può abilitare le funzionalità HTML5, ad esempio per visualizzare un controllo calendario, il simbolo di valuta appropriato per le impostazioni locali, i collegamenti di posta elettronica e così via.
  • Per impostazione predefinita, il browser esegue il rendering dei dati usando il formato corretto in base alle impostazioni locali.
  • L'attributo [DataType] può abilitare il framework di ASP.NET Core a scegliere il modello di campo corretto per il rendering dei dati. L'oggetto DisplayFormat, se usato da se stesso, usa il modello di stringa.

Nota: la convalida di jQuery non funziona con l'attributo [Range] e DateTime. Ad esempio, il codice seguente visualizzerà sempre un errore di convalida sul lato client, anche quando la data è compreso nell'intervallo specificato:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

È consigliabile evitare di compilare date hard nei modelli, quindi usare l'attributo [Range] ed DateTime è sconsigliato. Usare Configurazione per intervalli di date e altri valori soggetti a modifiche frequenti anziché specificarli nel codice.

Il codice seguente illustra la combinazione di attributi in una sola riga:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models;

public class Movie
{
    public int Id { get; set; }

    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; } = string.Empty;

    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; } = string.Empty;

    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; } = string.Empty;
}

Introduzione a Razor Pages e EF Core mostra operazioni avanzate EF Core con Razor Pages.

Applicare le migrazioni

DataAnnotations applicato alla classe modifica lo schema. Ad esempio, le annotazioni DataAnnotations applicate al campo Title:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • Limitano i caratteri a 60.
  • Non consentono un valore null.

La tabella Movie ha attualmente lo schema seguente:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Le modifiche dello schema precedenti non determinano la generazione di un'eccezione da parte di EF. Tuttavia, creare una migrazione in modo che lo schema sia coerente con il modello.

Scegliere NuGet Gestione pacchetti > console Gestione pacchetti dal menu Strumenti. Nella Console di Gestione pacchetti immettere i comandi seguenti:

Add-Migration New_DataAnnotations
Update-Database

Update-Database esegue il Up metodo della New_DataAnnotations classe .

Esaminare il metodo Up:

public partial class New_DataAnnotations : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

La tabella Movie aggiornata presenta lo schema seguente:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Pubblicare in Azure

Per informazioni sulla distribuzione in Azure, vedere Esercitazione: Creare un'app ASP.NET Core in Azure con database SQL.

Grazie per aver completato questa introduzione a Razor Pages. Iniziare a usare Razor Pages ed EF Core è un ottimo completamento di questa esercitazione.

Risorse aggiuntive

Passaggi successivi

In questa sezione la logica di convalida viene aggiunta al modello Movie. Le regole di convalida vengono applicate ogni volta che un utente crea o modifica un film.

Convalida

Un concetto di base dello sviluppo del software si chiama DRY ("Don't Repeat Yourself", Non ripeterti). Razor Pages incoraggia lo sviluppo in cui la funzionalità viene specificata una sola volta e viene riflessa in tutta l'app. DRY contribuisce a:

  • Ridurre la quantità di codice in un'app.
  • Rendere il codice meno soggetto ad errori e più facile da testare e gestire.

Il supporto di convalida fornito da Razor Pages ed Entity Framework è un buon esempio del principio DRY:

  • Le regole di convalida vengono specificate in modo dichiarativo in un'unica posizione, nella classe del modello.
  • Le regole vengono applicate ovunque nell'app.

Aggiungere regole di convalida al modello movie

Lo System.ComponentModel.DataAnnotations spazio dei nomi fornisce:

  • Set di attributi di convalida predefiniti applicati in modo dichiarativo a una classe o a una proprietà.
  • La formattazione di attributi come [DataType] questo è utile per la formattazione e non fornisce alcuna convalida.

Aggiornare la classe Movie per poter sfruttare gli attributi di convalida [Required], [StringLength], [RegularExpression] e [Range] predefiniti.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models;

public class Movie
{
    public int Id { get; set; }

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string Title { get; set; } = string.Empty;

    // [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
    [Required]
    [StringLength(30)]
    public string Genre { get; set; } = string.Empty;

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
    [StringLength(5)]
    [Required]
    public string Rating { get; set; } = string.Empty;
}

Gli attributi di convalida specificano il comportamento da imporre nelle proprietà del modello a cui vengono applicati:

  • Gli attributi [Required] e [MinimumLength] indicano che una proprietà deve avere un valore. Nulla impedisce a un utente di immettere spazi vuoti per soddisfare questa convalida.

  • L'attributo [RegularExpression] viene usato per limitare i caratteri che possono essere inseriti. Nel codice precedente: Genre

    • Deve includere solo lettere.
    • La prima lettera deve essere maiuscola. Gli spazi vuoti sono consentiti mentre i numeri e i caratteri speciali non sono consentiti.
  • RegularExpressionRating:

    • Richiede che il primo carattere sia una lettera maiuscola.
    • Consente i caratteri speciali e i numeri negli spazi successivi. "PG-13" è valido per una classificazione, ma non riesce per un oggetto Genre.
  • L'attributo [Range] vincola un valore all'interno di un intervallo specificato.

  • L'attributo [StringLength] può impostare una lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.

  • I tipi valore, ad esempio decimal, floatint, , DateTime, sono intrinsecamente necessari e non richiedono l'attributo [Required] .

Le regole di convalida precedenti vengono usate per la dimostrazione, non sono ottimali per un sistema di produzione. Ad esempio, il precedente impedisce l'immissione di un film con solo due caratteri e non consente caratteri speciali in Genre.

La presenza di regole di convalida applicate automaticamente da ASP.NET Core consente di:

  • Rendere l'app più affidabile.
  • Ridurre le probabilità di salvare dati non validi nel database.

Interfaccia utente degli errori di convalida nelle Razor pagine

Eseguire l'app e passare a Pages/Movies.

Selezionare il collegamento Crea nuovo. Completare il modulo con alcuni valori non validi. Quando la convalida del lato client jQuery rileva l'errore, viene visualizzato un messaggio di errore.

Movie view form with multiple jQuery client-side validation errors

Nota

È possibile che non si riesca a immettere virgole decimali nel campo. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .

Si noti come il modulo ha eseguito automaticamente il rendering di un messaggio di errore di convalida in ogni campo che contiene un valore non valido. Gli errori vengono applicati sia sul lato client, usando JavaScript che jQuery e lato server, quando un utente ha disabilitato JavaScript.

Un vantaggio significativo è che non c'era nessuna modifica del codice necessaria nelle pagine Create o Edit. Dopo l'applicazione delle annotazioni dei dati al modello, l'interfaccia utente di convalida è stata abilitata. Le Razor pagine create in questa esercitazione hanno selezionato automaticamente le regole di convalida, usando gli attributi di convalida per le proprietà della Movie classe modello. Convalida del test tramite la pagina Modifica, viene applicata la stessa convalida.

I dati del modulo non vengono registrati nel server fino a quando non sono presenti errori di convalida nel lato client. Verificare che i dati del modulo non siano stati registrati da uno o più degli approcci seguenti:

  • Inserire un punto di interruzione nel metodo OnPostAsync. Inviare il modulo selezionando Crea o Salva. Il punto di interruzione non viene mai raggiunto.
  • Usare lo Strumento Fiddler.
  • Usare gli strumenti di sviluppo del browser per monitorare il traffico di rete.

Convalida sul lato server

Quando JavaScript è disabilitato nel browser, l'invio del modulo con errori verrà inoltrato al server.

Facoltativo, convalida sul lato server del test:

  1. Disabilitare JavaScript nel browser. JavaScript può essere disabilitato usando gli strumenti di sviluppo del browser. Se JavaScript non può essere disabilitato nel browser, provare un altro browser.

  2. Impostare un punto di interruzione nel metodo OnPostAsync della pagina Crea o Modifica.

  3. Inviare un modulo con dati non validi.

  4. Verificare che lo stato del modello non sia valido:

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

In alternativa, disabilitare la convalida lato client nel server.

Il codice seguente illustra una parte dello scaffolding della Create.cshtml pagina in precedenza nell'esercitazione. Viene usato dalle pagine Crea e Modifica per:

  • Visualizzare il modulo iniziale.
  • Riprodurre di nuovo il modulo in caso di errore.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

L'helper tag di input usa gli attributi DataAnnotations e produce gli attributi HTML necessari per la convalida jQuery sul lato client. L'helper tag di convalida visualizza gli errori di convalida. Per altre informazioni, vedere Convalida.

Le pagine Create e Edit non dispongono di nessuna regola di convalida. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie. Queste regole di convalida vengono applicate automaticamente alle Razor pagine che modificano il Movie modello.

Quando la logica di convalida deve cambiare, avviene solo nel modello. La convalida viene applicata in modo coerente in tutta l'app, la logica di convalida viene definita in un'unica posizione. La convalida in un'unica posizione consente di mantenere il codice pulito e rende più semplice la gestione e l'aggiornamento.

Usare attributi DataType

Esaminare la classe Movie. Lo spazio dei nomi System.ComponentModel.DataAnnotations fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. L'attributo [DataType] viene applicato alle proprietà ReleaseDate e Price.

// [Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }

Gli [DataType] attributi forniscono:

  • Hint per il motore di visualizzazione per formattare i dati.
  • Fornisce attributi come <a> per l'URL e <a href="mailto:EmailAddress.com"> per la posta elettronica.

Usare l'attributo [RegularExpression] per convalidare il formato dei dati. L'attributo [DataType] viene usato per specificare un tipo di dati che è più specifico del tipo intrinseco del database. [DataType] gli attributi non sono attributi di convalida. Nell'app di esempio viene visualizzata solo la data, senza ora.

L'enumerazione DataType fornisce molti tipi di dati, ad esempio Date, TimePhoneNumber, Currency, EmailAddress, e altro ancora.

Attributi [DataType] :

  • Può abilitare l'app per fornire automaticamente funzionalità specifiche del tipo. Ad esempio, è possibile creare un collegamento mailto: per DataType.EmailAddress.
  • Può fornire un selettore DataType.Date di data nei browser che supportano HTML5.
  • Genera HTML 5 data-, pronunciato "trattino dati", attributi utilizzati dai browser HTML 5.
  • Non fornire alcuna convalida.

DataType.Date non specifica il formato della data visualizzata. Per impostazione predefinita, il campo dei dati viene visualizzato in base ai formati predefiniti per il valore CultureInfo del server.

L'annotazione dei dati [Column(TypeName = "decimal(18, 2)")] è necessaria per consentire a Entity Framework Core di eseguire correttamente il mapping di Price nella valuta del database. Per altre informazioni, vedere Tipi di dati.

L'attributo [DisplayFormat] viene usato per specificare in modo esplicito il formato della data:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

L'impostazione ApplyFormatInEditMode specifica che la formattazione verrà applicata quando viene visualizzato il valore per la modifica. Questo comportamento potrebbe non essere voluto per alcuni campi. Ad esempio, nei valori di valuta, il simbolo di valuta non è in genere desiderato nell'interfaccia utente di modifica.

L'attributo [DisplayFormat] può essere usato da solo, ma in genere è consigliabile usare l'attributo [DataType]. L'attributo [DataType] offre la semantica dei dati anziché specificarne il rendering in una schermata. L'attributo [DataType] offre i vantaggi seguenti che non sono disponibili con [DisplayFormat]:

  • Il browser può abilitare le funzionalità HTML5, ad esempio per visualizzare un controllo calendario, il simbolo di valuta appropriato per le impostazioni locali, i collegamenti di posta elettronica e così via.
  • Per impostazione predefinita, il browser esegue il rendering dei dati usando il formato corretto in base alle impostazioni locali.
  • L'attributo [DataType] può abilitare il framework di ASP.NET Core a scegliere il modello di campo corretto per il rendering dei dati. L'oggetto DisplayFormat, se usato da se stesso, usa il modello di stringa.

Nota: la convalida di jQuery non funziona con l'attributo [Range] e DateTime. Ad esempio, il codice seguente visualizzerà sempre un errore di convalida sul lato client, anche quando la data è compreso nell'intervallo specificato:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

È consigliabile evitare di compilare date hard nei modelli, quindi usare l'attributo [Range] ed DateTime è sconsigliato. Usare Configurazione per intervalli di date e altri valori soggetti a modifiche frequenti anziché specificarli nel codice.

Il codice seguente illustra la combinazione di attributi in una sola riga:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models;

public class Movie
{
    public int Id { get; set; }

    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; } = string.Empty;

    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; } = string.Empty;

    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; } = string.Empty;
}

Introduzione a Razor Pages e EF Core mostra operazioni avanzate EF Core con Razor Pages.

Applicare le migrazioni

DataAnnotations applicato alla classe modifica lo schema. Ad esempio, le annotazioni DataAnnotations applicate al campo Title:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • Limitano i caratteri a 60.
  • Non consentono un valore null.

La tabella Movie ha attualmente lo schema seguente:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Le modifiche dello schema precedenti non determinano la generazione di un'eccezione da parte di EF. Tuttavia, creare una migrazione in modo che lo schema sia coerente con il modello.

Scegliere NuGet Gestione pacchetti > console Gestione pacchetti dal menu Strumenti. Nella Console di Gestione pacchetti immettere i comandi seguenti:

Add-Migration New_DataAnnotations
Update-Database

Update-Database esegue il Up metodo della New_DataAnnotations classe .

Esaminare il metodo Up:

public partial class NewDataAnnotations : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

La tabella Movie aggiornata presenta lo schema seguente:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Pubblicare in Azure

Per informazioni sulla distribuzione in Azure, vedere Esercitazione: Creare un'app ASP.NET Core in Azure con database SQL.

Grazie per aver completato questa introduzione a Razor Pages. Iniziare a usare Razor Pages ed EF Core è un ottimo completamento di questa esercitazione.

Risorse aggiuntive

Passaggi successivi

In questa sezione la logica di convalida viene aggiunta al modello Movie. Le regole di convalida vengono applicate ogni volta che un utente crea o modifica un film.

Convalida

Un concetto di base dello sviluppo del software si chiama DRY ("Don't Repeat Yourself", Non ripeterti). Razor Pages incoraggia lo sviluppo in cui la funzionalità viene specificata una sola volta e viene riflessa in tutta l'app. DRY contribuisce a:

  • Ridurre la quantità di codice in un'app.
  • Rendere il codice meno soggetto ad errori e più facile da testare e gestire.

Il supporto di convalida fornito da Razor Pages ed Entity Framework è un buon esempio del principio DRY:

  • Le regole di convalida vengono specificate in modo dichiarativo in un'unica posizione, nella classe del modello.
  • Le regole vengono applicate ovunque nell'app.

Aggiungere regole di convalida al modello movie

Lo System.ComponentModel.DataAnnotations spazio dei nomi fornisce:

  • Set di attributi di convalida predefiniti applicati in modo dichiarativo a una classe o a una proprietà.
  • La formattazione di attributi come [DataType] questo è utile per la formattazione e non fornisce alcuna convalida.

Aggiornare la classe Movie per poter sfruttare gli attributi di convalida [Required], [StringLength], [RegularExpression] e [Range] predefiniti.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }

        [StringLength(60, MinimumLength = 3)]
        [Required]
        public string Title { get; set; } = string.Empty;

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [Range(1, 100)]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
        [Required]
        [StringLength(30)]
        public string Genre { get; set; } = string.Empty;

        [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
        [StringLength(5)]
        [Required]
        public string Rating { get; set; } = string.Empty;
    }
}

Gli attributi di convalida specificano il comportamento da imporre nelle proprietà del modello a cui vengono applicati:

  • Gli attributi [Required] e [MinimumLength] indicano che una proprietà deve avere un valore. Nulla impedisce a un utente di immettere spazi vuoti per soddisfare questa convalida.

  • L'attributo [RegularExpression] viene usato per limitare i caratteri che possono essere inseriti. Nel codice precedente: Genre

    • Deve includere solo lettere.
    • La prima lettera deve essere maiuscola. Gli spazi vuoti sono consentiti mentre i numeri e i caratteri speciali non sono consentiti.
  • RegularExpressionRating:

    • Richiede che il primo carattere sia una lettera maiuscola.
    • Consente i caratteri speciali e i numeri negli spazi successivi. "PG-13" è valido per una classificazione, ma non riesce per un oggetto Genre.
  • L'attributo [Range] vincola un valore all'interno di un intervallo specificato.

  • L'attributo [StringLength] può impostare una lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.

  • I tipi valore, ad esempio decimal, floatint, , DateTime, sono intrinsecamente necessari e non richiedono l'attributo [Required] .

Le regole di convalida precedenti vengono usate per la dimostrazione, non sono ottimali per un sistema di produzione. Ad esempio, il precedente impedisce l'immissione di un film con solo due caratteri e non consente caratteri speciali in Genre.

La presenza di regole di convalida applicate automaticamente da ASP.NET Core consente di:

  • Rendere l'app più affidabile.
  • Ridurre le probabilità di salvare dati non validi nel database.

Interfaccia utente degli errori di convalida nelle Razor pagine

Eseguire l'app e passare a Pages/Movies.

Selezionare il collegamento Crea nuovo. Completare il modulo con alcuni valori non validi. Quando la convalida del lato client jQuery rileva l'errore, viene visualizzato un messaggio di errore.

Movie view form with multiple jQuery client-side validation errors

Nota

È possibile che non si riesca a immettere virgole decimali nel campo. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .

Si noti come il modulo ha eseguito automaticamente il rendering di un messaggio di errore di convalida in ogni campo che contiene un valore non valido. Gli errori vengono applicati sia sul lato client, usando JavaScript che jQuery e lato server, quando un utente ha disabilitato JavaScript.

Un vantaggio significativo è che non c'era nessuna modifica del codice necessaria nelle pagine Create o Edit. Dopo l'applicazione delle annotazioni dei dati al modello, l'interfaccia utente di convalida è stata abilitata. Le Razor pagine create in questa esercitazione hanno selezionato automaticamente le regole di convalida, usando gli attributi di convalida per le proprietà della Movie classe modello. Convalida del test tramite la pagina Modifica, viene applicata la stessa convalida.

I dati del modulo non vengono registrati nel server fino a quando non sono presenti errori di convalida nel lato client. Verificare che i dati del modulo non siano stati registrati da uno o più degli approcci seguenti:

  • Inserire un punto di interruzione nel metodo OnPostAsync. Inviare il modulo selezionando Crea o Salva. Il punto di interruzione non viene mai raggiunto.
  • Usare lo Strumento Fiddler.
  • Usare gli strumenti di sviluppo del browser per monitorare il traffico di rete.

Convalida sul lato server

Quando JavaScript è disabilitato nel browser, l'invio del modulo con errori verrà inoltrato al server.

Facoltativo, convalida sul lato server del test:

  1. Disabilitare JavaScript nel browser. JavaScript può essere disabilitato usando gli strumenti di sviluppo del browser. Se non è possibile disabilitare JavaScript nel browser, provare un altro browser.

  2. Impostare un punto di interruzione nel metodo OnPostAsync della pagina Crea o Modifica.

  3. Inviare un modulo con dati non validi.

  4. Verificare che lo stato del modello non sia valido:

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

In alternativa, disabilitare la convalida lato client nel server.

Il codice seguente illustra una parte dello scaffolding della Create.cshtml pagina in precedenza nell'esercitazione. Viene usato dalle pagine Crea e Modifica per:

  • Visualizzare il modulo iniziale.
  • Riprodurre di nuovo il modulo in caso di errore.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

L'helper tag di input usa gli attributi DataAnnotations e produce gli attributi HTML necessari per la convalida jQuery sul lato client. L'helper tag di convalida visualizza gli errori di convalida. Per altre informazioni, vedere Convalida.

Le pagine Create e Edit non dispongono di nessuna regola di convalida. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie. Queste regole di convalida vengono applicate automaticamente alle Razor pagine che modificano il Movie modello.

Quando la logica di convalida deve cambiare, avviene solo nel modello. La convalida viene applicata in modo coerente in tutta l'applicazione, la logica di convalida viene definita in un'unica posizione. La convalida in un'unica posizione consente di mantenere il codice pulito e rende più semplice la gestione e l'aggiornamento.

Usare attributi DataType

Esaminare la classe Movie. Lo spazio dei nomi System.ComponentModel.DataAnnotations fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. L'attributo [DataType] viene applicato alle proprietà ReleaseDate e Price.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }

Gli [DataType] attributi forniscono:

  • Hint per il motore di visualizzazione per formattare i dati.
  • Fornisce attributi come <a> per l'URL e <a href="mailto:EmailAddress.com"> per la posta elettronica.

Usare l'attributo [RegularExpression] per convalidare il formato dei dati. L'attributo [DataType] viene usato per specificare un tipo di dati che è più specifico del tipo intrinseco del database. [DataType] gli attributi non sono attributi di convalida. Nell'applicazione di esempio, viene visualizzata solo la data, senza l'ora.

L'enumerazione DataType fornisce molti tipi di dati, ad esempio Date, TimePhoneNumber, Currency, EmailAddress, e altro ancora.

Attributi [DataType] :

  • Può abilitare l'applicazione per fornire automaticamente funzionalità specifiche del tipo. Ad esempio, è possibile creare un collegamento mailto: per DataType.EmailAddress.
  • Può fornire un selettore DataType.Date di data nei browser che supportano HTML5.
  • Genera HTML 5 data-, pronunciato "trattino dati", attributi utilizzati dai browser HTML 5.
  • Non fornire alcuna convalida.

DataType.Date non specifica il formato della data visualizzata. Per impostazione predefinita, il campo dei dati viene visualizzato in base ai formati predefiniti per il valore CultureInfo del server.

L'annotazione dei dati [Column(TypeName = "decimal(18, 2)")] è necessaria per consentire a Entity Framework Core di eseguire correttamente il mapping di Price nella valuta del database. Per altre informazioni, vedere Tipi di dati.

L'attributo [DisplayFormat] viene usato per specificare in modo esplicito il formato della data:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

L'impostazione ApplyFormatInEditMode specifica che la formattazione verrà applicata quando viene visualizzato il valore per la modifica. Questo comportamento potrebbe non essere voluto per alcuni campi. Ad esempio, nei valori di valuta, il simbolo di valuta non è in genere desiderato nell'interfaccia utente di modifica.

L'attributo [DisplayFormat] può essere usato da solo, ma in genere è consigliabile usare l'attributo [DataType]. L'attributo [DataType] offre la semantica dei dati anziché specificarne il rendering in una schermata. L'attributo [DataType] offre i vantaggi seguenti che non sono disponibili con [DisplayFormat]:

  • Il browser può abilitare le funzionalità HTML5, ad esempio per visualizzare un controllo calendario, il simbolo di valuta appropriato per le impostazioni locali, i collegamenti di posta elettronica e così via.
  • Per impostazione predefinita, il browser esegue il rendering dei dati usando il formato corretto in base alle impostazioni locali.
  • L'attributo [DataType] può abilitare il framework di ASP.NET Core a scegliere il modello di campo corretto per il rendering dei dati. L'oggetto DisplayFormat, se usato da se stesso, usa il modello di stringa.

Nota: la convalida di jQuery non funziona con l'attributo [Range] e DateTime. Ad esempio, il codice seguente visualizzerà sempre un errore di convalida sul lato client, anche quando la data è compreso nell'intervallo specificato:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

È consigliabile evitare di compilare date hard nei modelli, quindi usare l'attributo [Range] ed DateTime è sconsigliato. Usare Configurazione per intervalli di date e altri valori soggetti a modifiche frequenti anziché specificarli nel codice.

Il codice seguente illustra la combinazione di attributi in una sola riga:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }

        [StringLength(60, MinimumLength = 3)]
        public string Title { get; set; } = string.Empty;

        [Display(Name = "Release Date"), DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
        public string Genre { get; set; } = string.Empty;

        [Range(1, 100), DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
        public string Rating { get; set; } = string.Empty;
    }
}

Introduzione a Razor Pages e EF Core mostra operazioni avanzate EF Core con Razor Pages.

Applicare le migrazioni

DataAnnotations applicato alla classe modifica lo schema. Ad esempio, le annotazioni DataAnnotations applicate al campo Title:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; } = string.Empty;
  • Limitano i caratteri a 60.
  • Non consentono un valore null.

La tabella Movie ha attualmente lo schema seguente:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Le modifiche dello schema precedenti non determinano la generazione di un'eccezione da parte di EF. Tuttavia, creare una migrazione in modo che lo schema sia coerente con il modello.

Scegliere NuGet Gestione pacchetti > console Gestione pacchetti dal menu Strumenti. Nella Console di Gestione pacchetti immettere i comandi seguenti:

Add-Migration New_DataAnnotations
Update-Database

Update-Database esegue il Up metodo della New_DataAnnotations classe .

Esaminare il metodo Up:

public partial class New_DataAnnotations : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            type: "nvarchar(60)",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            type: "nvarchar(5)",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            type: "nvarchar(30)",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldType: "nvarchar(max)");
    }

La tabella Movie aggiornata presenta lo schema seguente:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Pubblicare in Azure

Per informazioni sulla distribuzione in Azure, vedere Esercitazione: Creare un'app ASP.NET Core in Azure con database SQL.

Grazie per aver completato questa introduzione a Razor Pages. Iniziare a usare Razor Pages ed EF Core è un ottimo completamento di questa esercitazione.

Risorse aggiuntive

Passaggi successivi

In questa sezione la logica di convalida viene aggiunta al modello Movie. Le regole di convalida vengono applicate ogni volta che un utente crea o modifica un film.

Convalida

Un concetto di base dello sviluppo del software si chiama DRY ("Don't Repeat Yourself", Non ripeterti). Razor Pages incoraggia lo sviluppo in cui la funzionalità viene specificata una sola volta e viene riflessa in tutta l'app. DRY contribuisce a:

  • Ridurre la quantità di codice in un'app.
  • Rendere il codice meno soggetto ad errori e più facile da testare e gestire.

Il supporto di convalida fornito da Razor Pages ed Entity Framework è un buon esempio del principio DRY:

  • Le regole di convalida vengono specificate in modo dichiarativo in un'unica posizione, nella classe del modello.
  • Le regole vengono applicate ovunque nell'app.

Aggiungere regole di convalida al modello movie

Lo DataAnnotations spazio dei nomi fornisce:

  • Set di attributi di convalida predefiniti applicati in modo dichiarativo a una classe o a una proprietà.
  • La formattazione di attributi come [DataType] questo è utile per la formattazione e non fornisce alcuna convalida.

Aggiornare la classe Movie per poter sfruttare gli attributi di convalida [Required], [StringLength], [RegularExpression] e [Range] predefiniti.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace RazorPagesMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }

        [StringLength(60, MinimumLength = 3)]
        [Required]
        public string Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        [Range(1, 100)]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
        [Required]
        [StringLength(30)]
        public string Genre { get; set; }

        [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
        [StringLength(5)]
        [Required]
        public string Rating { get; set; }
    }
}

Gli attributi di convalida specificano il comportamento da imporre nelle proprietà del modello a cui vengono applicati:

  • Gli attributi [Required] e [MinimumLength] indicano che una proprietà deve avere un valore. Nulla impedisce a un utente di immettere spazi vuoti per soddisfare questa convalida.

  • L'attributo [RegularExpression] viene usato per limitare i caratteri che possono essere inseriti. Nel codice precedente: Genre

    • Deve includere solo lettere.
    • La prima lettera deve essere maiuscola. Gli spazi vuoti sono consentiti mentre i numeri e i caratteri speciali non sono consentiti.
  • RegularExpressionRating:

    • Richiede che il primo carattere sia una lettera maiuscola.
    • Consente i caratteri speciali e i numeri negli spazi successivi. "PG-13" è valido per una classificazione, ma non riesce per un oggetto Genre.
  • L'attributo [Range] vincola un valore all'interno di un intervallo specificato.

  • L'attributo [StringLength] può impostare una lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.

  • I tipi valore, ad esempio decimal, floatint, , DateTime, sono intrinsecamente necessari e non richiedono l'attributo [Required] .

Le regole di convalida precedenti vengono usate per la dimostrazione, non sono ottimali per un sistema di produzione. Ad esempio, il precedente impedisce l'immissione di un film con solo due caratteri e non consente caratteri speciali in Genre.

La presenza di regole di convalida applicate automaticamente da ASP.NET Core consente di:

  • Rendere l'app più affidabile.
  • Ridurre le probabilità di salvare dati non validi nel database.

Interfaccia utente degli errori di convalida nelle Razor pagine

Eseguire l'app e passare a Pages/Movies.

Selezionare il collegamento Crea nuovo. Completare il modulo con alcuni valori non validi. Quando la convalida del lato client jQuery rileva l'errore, viene visualizzato un messaggio di errore.

Movie view form with multiple jQuery client-side validation errors

Nota

È possibile che non si riesca a immettere virgole decimali nel campo. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .

Si noti come il modulo ha eseguito automaticamente il rendering di un messaggio di errore di convalida in ogni campo che contiene un valore non valido. Gli errori vengono applicati sia sul lato client, usando JavaScript che jQuery e lato server, quando un utente ha disabilitato JavaScript.

Un vantaggio significativo è che non c'era nessuna modifica del codice necessaria nelle pagine Create o Edit. Dopo l'applicazione delle annotazioni dei dati al modello, l'interfaccia utente di convalida è stata abilitata. Le Razor pagine create in questa esercitazione hanno selezionato automaticamente le regole di convalida, usando gli attributi di convalida per le proprietà della Movie classe modello. Convalida del test tramite la pagina Modifica, viene applicata la stessa convalida.

I dati del modulo non vengono registrati nel server fino a quando non sono presenti errori di convalida nel lato client. Verificare che i dati del modulo non siano stati registrati da uno o più degli approcci seguenti:

  • Inserire un punto di interruzione nel metodo OnPostAsync. Inviare il modulo selezionando Crea o Salva. Il punto di interruzione non viene mai raggiunto.
  • Usare lo Strumento Fiddler.
  • Usare gli strumenti di sviluppo del browser per monitorare il traffico di rete.

Convalida sul lato server

Quando JavaScript è disabilitato nel browser, l'invio del modulo con errori verrà inoltrato al server.

Facoltativo, convalida sul lato server del test:

  1. Disabilitare JavaScript nel browser. JavaScript può essere disabilitato usando gli strumenti di sviluppo del browser. Se JavaScript non può essere disabilitato nel browser, provare un altro browser.

  2. Impostare un punto di interruzione nel metodo OnPostAsync della pagina Crea o Modifica.

  3. Inviare un modulo con dati non validi.

  4. Verificare che lo stato del modello non sia valido:

     if (!ModelState.IsValid)
     {
        return Page();
     }
    

In alternativa, disabilitare la convalida lato client nel server.

Il codice seguente illustra una parte dello scaffolding della Create.cshtml pagina in precedenza nell'esercitazione. Viene usato dalle pagine Crea e Modifica per:

  • Visualizzare il modulo iniziale.
  • Riprodurre di nuovo il modulo in caso di errore.
<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Movie.Title" class="control-label"></label>
        <input asp-for="Movie.Title" class="form-control" />
        <span asp-validation-for="Movie.Title" class="text-danger"></span>
    </div>

L'helper tag di input usa gli attributi DataAnnotations e produce gli attributi HTML necessari per la convalida jQuery sul lato client. L'helper tag di convalida visualizza gli errori di convalida. Per altre informazioni, vedere Convalida.

Le pagine Create e Edit non dispongono di nessuna regola di convalida. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie. Queste regole di convalida vengono applicate automaticamente alle Razor pagine che modificano il Movie modello.

Quando la logica di convalida deve cambiare, avviene solo nel modello. La convalida viene applicata in modo coerente in tutta l'applicazione, la logica di convalida viene definita in un'unica posizione. La convalida in un'unica posizione consente di mantenere il codice pulito e rende più semplice la gestione e l'aggiornamento.

Usare attributi DataType

Esaminare la classe Movie. Lo spazio dei nomi System.ComponentModel.DataAnnotations fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. L'attributo [DataType] viene applicato alle proprietà ReleaseDate e Price.

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }

Gli [DataType] attributi forniscono:

  • Hint per il motore di visualizzazione per formattare i dati.
  • Fornisce attributi come <a> per l'URL e <a href="mailto:EmailAddress.com"> per la posta elettronica.

Usare l'attributo [RegularExpression] per convalidare il formato dei dati. L'attributo [DataType] viene usato per specificare un tipo di dati che è più specifico del tipo intrinseco del database. [DataType] gli attributi non sono attributi di convalida. Nell'applicazione di esempio, viene visualizzata solo la data, senza l'ora.

L'enumerazione DataType fornisce molti tipi di dati, ad esempio Date, TimePhoneNumber, Currency, EmailAddress, e altro ancora.

Attributi [DataType] :

  • Può abilitare l'applicazione per fornire automaticamente funzionalità specifiche del tipo. Ad esempio, è possibile creare un collegamento mailto: per DataType.EmailAddress.
  • Può fornire un selettore DataType.Date di data nei browser che supportano HTML5.
  • Genera HTML 5 data-, pronunciato "trattino dati", attributi utilizzati dai browser HTML 5.
  • Non fornire alcuna convalida.

DataType.Date non specifica il formato della data visualizzata. Per impostazione predefinita, il campo dei dati viene visualizzato in base ai formati predefiniti per il valore CultureInfo del server.

L'annotazione dei dati [Column(TypeName = "decimal(18, 2)")] è necessaria per consentire a Entity Framework Core di eseguire correttamente il mapping di Price nella valuta del database. Per altre informazioni, vedere Tipi di dati.

L'attributo [DisplayFormat] viene usato per specificare in modo esplicito il formato della data:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

L'impostazione ApplyFormatInEditMode specifica che la formattazione verrà applicata quando viene visualizzato il valore per la modifica. Questo comportamento potrebbe non essere voluto per alcuni campi. Ad esempio, nei valori di valuta, il simbolo di valuta non è in genere desiderato nell'interfaccia utente di modifica.

L'attributo [DisplayFormat] può essere usato da solo, ma in genere è consigliabile usare l'attributo [DataType]. L'attributo [DataType] offre la semantica dei dati anziché specificarne il rendering in una schermata. L'attributo [DataType] offre i vantaggi seguenti che non sono disponibili con [DisplayFormat]:

  • Il browser può abilitare le funzionalità HTML5, ad esempio per visualizzare un controllo calendario, il simbolo di valuta appropriato per le impostazioni locali, i collegamenti di posta elettronica e così via.
  • Per impostazione predefinita, il browser esegue il rendering dei dati usando il formato corretto in base alle impostazioni locali.
  • L'attributo [DataType] può abilitare il framework di ASP.NET Core a scegliere il modello di campo corretto per il rendering dei dati. L'oggetto DisplayFormat, se usato da se stesso, usa il modello di stringa.

Nota: la convalida di jQuery non funziona con l'attributo [Range] e DateTime. Ad esempio, il codice seguente visualizzerà sempre un errore di convalida sul lato client, anche quando la data è compreso nell'intervallo specificato:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

È consigliabile evitare di compilare date hard nei modelli, quindi usare l'attributo [Range] ed DateTime è sconsigliato. Usare Configurazione per intervalli di date e altri valori soggetti a modifiche frequenti anziché specificarli nel codice.

Il codice seguente illustra la combinazione di attributi in una sola riga:

public class Movie
{
    public int ID { get; set; }

    [StringLength(60, MinimumLength = 3)]
    public string Title { get; set; }

    [Display(Name = "Release Date"), DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$"), Required, StringLength(30)]
    public string Genre { get; set; }

    [Range(1, 100), DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$"), StringLength(5)]
    public string Rating { get; set; }
}

Introduzione a Razor Pages e EF Core mostra operazioni avanzate EF Core con Razor Pages.

Applicare le migrazioni

DataAnnotations applicato alla classe modifica lo schema. Ad esempio, le annotazioni DataAnnotations applicate al campo Title:

[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
  • Limitano i caratteri a 60.
  • Non consentono un valore null.

La tabella Movie ha attualmente lo schema seguente:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (MAX)  NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (MAX)  NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (MAX)  NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Le modifiche dello schema precedenti non determinano la generazione di un'eccezione da parte di EF. Tuttavia, creare una migrazione in modo che lo schema sia coerente con il modello.

Scegliere NuGet Gestione pacchetti > console Gestione pacchetti dal menu Strumenti. Nella Console di Gestione pacchetti immettere i comandi seguenti:

Add-Migration New_DataAnnotations
Update-Database

Update-Database esegue i metodi Up della classe New_DataAnnotations. Esaminare il metodo Up:

public partial class New_DataAnnotations : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "Title",
            table: "Movie",
            maxLength: 60,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);

        migrationBuilder.AlterColumn<string>(
            name: "Rating",
            table: "Movie",
            maxLength: 5,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);

        migrationBuilder.AlterColumn<string>(
            name: "Genre",
            table: "Movie",
            maxLength: 30,
            nullable: false,
            oldClrType: typeof(string),
            oldNullable: true);
    }

La tabella Movie aggiornata presenta lo schema seguente:

CREATE TABLE [dbo].[Movie] (
    [ID]          INT             IDENTITY (1, 1) NOT NULL,
    [Title]       NVARCHAR (60)   NOT NULL,
    [ReleaseDate] DATETIME2 (7)   NOT NULL,
    [Genre]       NVARCHAR (30)   NOT NULL,
    [Price]       DECIMAL (18, 2) NOT NULL,
    [Rating]      NVARCHAR (5)    NOT NULL,
    CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED ([ID] ASC)
);

Pubblicare in Azure

Per informazioni sulla distribuzione in Azure, vedere Esercitazione: Creare un'app ASP.NET Core in Azure con database SQL.

Grazie per aver completato questa introduzione a Razor Pages. Iniziare a usare Razor Pages ed EF Core è un ottimo completamento di questa esercitazione.

Modelli di app Web affidabili

Per indicazioni sulla creazione di un'app moderna, affidabile, affidabile, affidabile, testabile, conveniente e scalabile ASP.NET Core, indipendentemente dal fatto che si tratti di un'app esistente o di refactoring di un'app esistente, vedi Modello di app Web Reliable Web for.NETYouTube.

Risorse aggiuntive

Passaggi successivi