
Partager:
Ancien développeur .NET Advocate @Vonage, ingénieur logiciel polyglotte full-stack, AI/ML
Créer une application Secret Santa avec Blazor
Temps de lecture : 14 minutes
L'Avent est une période d'anticipation. Bien sûr, il y a une anticipation spirituelle fondamentale que beaucoup d'entre nous ressentent à l'approche de Noël. Il y a aussi l'anticipation du temps libre pour se détendre et se réjouir avec nos familles dans le cadre de nos traditions.
Dans l'esprit de Avent C#permettez-moi de vous faire part de la manière dont ma famille maintiendra ses traditions en ces temps difficiles. Cette année, j'ai créé une application Blazor pour virtualiser notre jeu annuel du Père Noël secret. Elle permet aux participants de s'inscrire avec leur numéro de téléphone et leur indique par message à qui ils doivent envoyer un cadeau.
Le problème
Chaque année, nous organisons un échange de cadeaux avec le Père Noël secret. Ma femme s'adresse à tous les membres de la famille pour savoir qui souhaite participer. Le nombre fluctue en fonction de l'engagement des jeunes membres de la famille. En général, à la fin de l'échange, nous avons une quinzaine de participants.
Theresa achète ensuite des cartes pour chaque participant et remplit les règles du jeu. Par exemple, ne pas dépenser plus de xx dollars. Elle met ensuite toutes les cartes dans des enveloppes et, le jour de Thanksgiving (le quatrième jeudi de novembre), nous nous réunissons pour distribuer les cartes.
Chaque année, nous rencontrons un problème : invariablement, quelques participants ne sont pas présents au dîner de Thanksgiving. Notre famille est répartie équitablement entre New York, le New Jersey et la Floride. Cette situation pose un problème pratique, car nous ne pouvons pas attribuer au hasard un Père Noël secret à une personne absente, qui risquerait de s'en prendre à elle-même. Par le passé, nous avons toujours réussi à contourner ce problème en demandant à une personne, qui ne participe pas, de sélectionner les absents pour s'assurer qu'ils ne se reçoivent pas eux-mêmes. Ensuite, ma femme adresse toutes les enveloppes aux personnes concernées et les envoie.
Cette année, au lieu d'une ou deux personnes absentes, il en manquait une douzaine, et comme personne n'était présent pour arbitrer le processus de sélection afin de s'assurer que personne ne s'y retrouve, nous avons dû faire preuve de créativité.
Aller directement au code
Si vous souhaitez passer outre ce tutoriel et lancer votre propre jeu Secret Santa, tout le code est disponible dans GitHub
Conditions préalables
Vous aurez besoin de la dernière version du .NET SDK
J'utilise Visual Studio 2019 pour cette démo. Vous pouvez utiliser VS Code si vous le souhaitez
Je vais utiliser Postgres pour cette démonstration. Pour les besoins de cette démonstration, je supposerai que vous avez installé le serveur. Vous pouvez utiliser n'importe quelle base de données, à condition de mettre à jour le contexte de la base de données pour celle-ci
Je l'ai déployé sur Azure - si vous choisissez de le faire, c'est à vous de voir, mais pour l'exécuter, vous n'avez besoin que d'IIS Express ou de
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.
Créer le projet
La première étape consiste à créer notre projet. Naviguez vers votre répertoire de développement, et exécutez la commande suivante dans votre terminal :
dotnet new blazorserver --no-https -n SecretSantaCette commande créera un dossier et un projet appelés SecretSanta. run cd SecretSanta pour naviguer dans ce répertoire et exécuter les commandes suivantes :
dotnet add package Vonage
dotnet add package Microsoft.AspNetCore.Components.Authorization
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL Construire un modèle de données
Nous allons utiliser Entity Framework Core pour gérer toutes nos données. Comme je l'ai mentionné plus tôt, j'utilise Postgres pour cela, mais il n'y a pas de nécessité absolue d'utiliser Postgres. Vous pouvez utiliser la base de données qui vous convient le mieux.
Créez un fichier appelé SecretSantaParticipant. et ajoutez-y ce qui suit :
public class SecretSantaParticipant
{
[Key]
[Required]
[Phone(ErrorMessage ="Phone Number must be a fully " +
"formed phone number with no special charecters")]
public string PhoneNumber { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Address { get; set; }
public string GiftIdeas { get; set; }
public string RequestId { get; set; }
[ForeignKey("MatchForeignKey")]
public SecretSantaParticipant Match { get; set; }
public string Role { get; set; }
public bool HasGiver { get; set; }
[ForeignKey("GiverForeignKey")]
public SecretSantaParticipant Giver { get; set; }
}Cette classe sera le modèle de données que nous transmettrons entre notre client et notre serveur pour gérer les comptes du Père Noël secret.
Créer un contexte de base de données
Créer un fichier appelé SecretSantaContext.cs. Faites en sorte que la SecretSantaContext étende DbContext et ajoutez-y ce qui suit.
private readonly IConfiguration _config;
public DbSet<SecretSantaParticipant> Participants { get; set; }
public SecretSantaContext(IConfiguration config) => _config = config;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>
optionsBuilder.UseNpgsql(_config["CONNECTION_STRING"]);Remarque : c'est à cet endroit que vous devez apporter les modifications nécessaires pour utiliser une autre base de données si vous le souhaitez.
Créer un fournisseur d'authentification
Nous utiliserons l Verify API de Vonage de Vonage pour gérer la connexion de nos utilisateurs. Nous aurons un fichier personnalisé AuthenticationStateProvider personnalisé qui gérera l'état de connexion de nos utilisateurs. Créer un nouveau fichier AuthProvider.cs et faites en sorte que la AuthProvider étende la classe AuthenticationStateProvider.
Dans la classe AuthProvider ajouter un membre privé ClaimsIdentiy appelé _identity:
private ClaimsIdentity _identity = new ClaimsIdentity();Nous initialisons cette identité de réclamation de manière anonyme dans un premier temps, afin que l'utilisateur n'ait aucune réclamation lorsqu'il arrive pour la première fois sur notre page, ce qui signifie qu'il devra compléter une séquence de connexion.
Obtenir l'état d'authentification
Ensuite, nous allons fournir un moyen d'obtenir l'état d'authentification en surchargeant la méthode GetAuthenticationStateAsync en surchargeant la méthode Cette méthode renverra un état d'authentification avec notre identité.
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
return await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(_identity)));
} Mise à jour de l'état d'authentification
Ce fournisseur d'état sera rattaché à la session d'un utilisateur particulier et indiquera à notre application ce à quoi il est autorisé à accéder sur une page donnée. En conséquence, nous avons besoin d'un moyen de mettre à jour l'état d'authentification.
Pour ce faire, nous ajouterons une méthode de connexion et de déconnexion. La méthode Login AuthorizeUser créera un nouveau ClaimsIdentity avec le numéro de téléphone de l'utilisateur et son rôle (s'il est administrateur, il pourra voir plus de choses). Elle notifiera ensuite à toute personne regardant la page AuthProvider que l'état d'authentification a changé :
public void AuthorizeUser(SecretSantaParticipant participant)
{
var claims = new[] { new Claim(ClaimTypes.Name, participant.PhoneNumber) };
claims.Append(new Claim(ClaimTypes.Role, participant.Role));
_identity = new ClaimsIdentity(claims,"apiauth_type");
var user = new ClaimsPrincipal(_identity);
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));
}Inversement, la méthode LogOutUser réinitialisera la méthode ClaimsIdentity à anonyme et notifiera tout ce qui écoute le fournisseur d'état qu'il a mis à jour l'état d'authentification.
public void LogOutUser()
{
_identity = new ClaimsIdentity();
var user = new ClaimsPrincipal(_identity);
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));
} Créer un service de Père Noël secret
Nous allons ajouter un service injectable de dépendance pour nous permettre d'effectuer toutes les opérations de backend dont notre application a besoin. Ce service comprend la gestion de la vérification, la lecture et l'écriture dans la base de données, et l'envoi de messages à nos participants. Créez un fichier appelé SecretSantaService.cs.
Nous allons injecter trois éléments de dépendance dans notre SecretSantaService:
Notre
VonageClientqui traitera toutes les requêtes de l'API Vonage pour nousNotre
SecretSantaContextqui arbitrera toutes nos connexions à la base de donnéesUn objet
IConfigurationqui nous donne accès à la configuration de l'application
Déclarez-les comme tels :
private readonly VonageClient _client;
private readonly SecretSantaContext _db;
private readonly IConfiguration _config;Puis nous les injectons dans notre service via le constructeur :
public SecretSantaService(VonageClient client, SecretSantaContext context, IConfiguration config)
{
_client = client;
_db = context;
_config = config;
} Créer une demande de Verify
Nous allons utiliser le numéro de téléphone du participant pour vérifier l'accès à son Account. Cette méthode créera une sorte de 1FA pour la connexion. Je n'utiliserais pas 1FA dans des circonstances où j'aurais besoin d'une connexion sécurisée, mais comme il s'agit juste d'un jeu familial amusant, et que notre objectif est de vérifier le numéro de téléphone, je vais m'en tenir là.
Pour lancer le 1FA, nous allons ajouter une méthode pour démarrer la vérification et renvoyer l'ID de Verify kickoff. Nous ferons cela avec l'API Verify de Vonage. À ce stade, il ne s'agit que d'une seule ligne de code :
public async Task<string> StartVeriy(string number)
{
return (await _client.VerifyClient.VerifyRequestAsync(
new VerifyRequest
{
Brand = "North Pole Access",
SenderId = _config["VONAGE_NUMBER"],
Number= number,
WorkflowId = VerifyRequest.Workflow.SMS,
PinExpiry=300
}
)).RequestId;
} Confirmation de la poignée
Lorsqu'un utilisateur saisit son numéro pour se connecter ou créer son Account, nous pouvons demander à l'API Verify de Vonage d'effectuer une demande de vérification. Nous pouvons le faire en utilisant la méthode VerifyCheck dans le client de Verify de Vonage :
public async Task<bool> ConfirmCode(string id, string code)
{
try
{
var result = await _client.VerifyClient.VerifyCheckAsync(new VerifyCheckRequest { Code = code, RequestId = id });
return true;
}
catch (VonageVerifyResponseException)
{
return false;
}
} Utilisateurs de la lecture aléatoire
La méthode suivante consiste à mélanger les utilisateurs et à leur attribuer une mission pour le jeu du Père Noël secret. Cette méthode passe en revue tous les utilisateurs qui n'ont pas de mission de Père Noël secret et leur attribue au hasard une sélection parmi les utilisateurs qui n'ont pas encore de Père Noël secret. Giver encore.
public async Task ShuffleUsers()
{
var rnd = new Random(DateTime.UtcNow.Second);
var participants = _db.Participants.ToList();
while (participants.Any(x => !x.HasGiver))
{
var participant1 = participants.First(x => !x.HasGiver);
var unmatched = participants.Where(x => x.Match == null && x.PhoneNumber !=participant1.PhoneNumber);
if(unmatched.Count() == 0)
{
System.Diagnostics.Debug.WriteLine("encountered Edge case");
var match = participants.First(x => x.PhoneNumber != participant1.PhoneNumber);
participant1.Giver = match;
participant1.Match = match.Match;
match.Match.Giver = participant1;
match.Match = participant1;
participant1.HasGiver = true;
}
else
{
var match = unmatched.ToList().ElementAt(rnd.Next(unmatched.Count() - 1));
participant1.Giver = match;
participant1.HasGiver = true;
match.Match = participant1;
}
}
await _db.SaveChangesAsync();
} Informer les participants
Maintenant que les utilisateurs se sont mélangés, nous devons dire à chacun qui est son correspondant !
Pour ce faire, nous allons utiliser l'API SMS de Vonage. Nous passerons en revue nos participants et leur dirons qui est leur Père Noël secret, combien ils doivent dépenser et où ils doivent envoyer leur cadeau. Je fais cette partie avec un LVN de Vonage, qui se limite à un message par seconde. L'application attendra donc 1 seconde entre chaque demande. Comme nous avons quelques jeunes participants à ce jeu, nous allons leur dire que le Père Noël a besoin de leur aide !
public async Task NotifyUsers()
{
foreach(var participant in _db.Participants)
{
var message = $"Hello {participant.Name} this is Santa. " +
$"I'm desperately busy up here at the North Pole and need your help. " +
$"Could you help me out and find a gift for {participant.Match.Name}? " +
$"It doesn't need to extravagant, I wouldn't spend more than $25." +
$"You can send the gift directly to them at: {participant.Match.Address}. ";
if (!string.IsNullOrEmpty(participant.Match.GiftIdeas))
{
message += $"They wrote me with some ideas of what to get them: {participant.Match.GiftIdeas}";
}
await _client.SmsClient.SendAnSmsAsync(new SendSmsRequest
{
To=participant.PhoneNumber,
From=_config["VONAGE_NUMBER"],
Text=message
});
Thread.Sleep(1000);
}
} Envoyer des mises à jour
Il n'y a pas grand-chose qu'un utilisateur puisse configurer après s'être inscrit, mais j'ai décidé de lui permettre de modifier son adresse et les idées de cadeaux qu'il souhaite offrir à son Père Noël secret. Par conséquent, lorsqu'un utilisateur modifiera son Account, nous enverrons un SMS au donateur pour l'informer de la mise à jour :
public async Task NotifyUserOfUpdate(SecretSantaParticipant participant)
{
if(participant.Match != null)
{
var msg = $"Hello, this is Santa again, just wanted to let you know that your match {participant.Name} sent me some updates:" +
$" Their Address is {participant.Address}.";
if (!string.IsNullOrEmpty(participant.GiftIdeas))
{
msg += $" And they indicated they'd want {participant.GiftIdeas}";
}
await _client.SmsClient.SendAnSmsAsync(new SendSmsRequest
{
To = participant.Match.PhoneNumber,
From = _config["VONAGE_NUMBER"],
Text = msg
});
}
} Configuration de l'intergiciel
Nous utilisons pour cela plusieurs éléments d'intergiciel. Nous utilisons le contexte de base de données pour maintenir une connexion à notre base de données. Nous utilisons le contexte VonageClient pour faire des demandes d'API à Vonage, et nous utilisons un objet de configuration pour extraire notre numéro Vonage. Nous utilisons notre AuthProvider pour extraire notre état d'autorisation.
Nous allons devoir enregistrer tous ces services avec notre application. Pour cela, allez dans Startup.cs et trouvez la méthode ConfigureServices et trouvez la méthode Ajoutez-y ce qui suit :
services.AddDbContext<SecretSantaContext>();
var creds = Credentials.FromApiKeyAndSecret(Configuration["API_KEY"], Configuration["API_SECRET"]);
services.AddSingleton(new VonageClient(creds));
services.AddScoped<SecretSantaService>();
services.AddScoped<AuthenticationStateProvider, AuthProvider>();Les services étant tous configurés, nous devons maintenant nous assurer que nous activons l'authentification et l'autorisation pour tout autoriser. Restez dans le fichier Startup.cs et allez à la méthode Configure et ajoutez-y les deux lignes suivantes :
app.UseAuthorization();
app.UseAuthentication(); Construire le Frontend
Avec tous les éléments de l'application dorsale mis au point, il ne reste plus qu'à construire notre application frontale. Puisque nous utilisons un composant d'autorisation pour propager notre état d'autorisation à tous les composants, nous devrons d'abord envelopper toute l'application dans un composant d'autorisation. CascadingAuthenticationState ouvrez App.razor et entourer l'application entière avec des balises <CascadingAuthenticationState></CascadingAuthenticationState> tags.
Ajouter un composant de connexion
Ajouter un fichier Login.razor sous le dossier /Pages dans lequel nous allons ajouter une entrée pour gérer notre connexion et un bouton pour effectuer la connexion comme suit :
@inject SecretSantaService SecretSantaService
@inject SecretSantaContext Database
@inject NavigationManager NavigationManager
@using Vonage.Verify
<h3>Login</h3>
Phone Number:
<input class="input-group-text" @bind="_phoneNumber" />
<button class="btn-group-sm" @onclick="StartLogin">Login</button>
<br />
@if (_numberExists == false)
{
<p1>Nubmer Not Registered</p1>
<br />
}
<a href="/registration">Register here</a>
Ensuite, nous allons ajouter un peu de logique pour effectuer la connexion. Nous allons lancer une demande de vérification, qui enverra un code à l'utilisateur si la vérification n'a pas commencé. Dans le cas contraire, il sera dirigé vers la page de confirmation pour saisir son OTP.
@code {
private string _phoneNumber;
private bool? _numberExists;
private async Task StartLogin()
{
if (!_phoneNumber.StartsWith("1"))
{
_phoneNumber = "1" + _phoneNumber;
}
var user = Database.Participants.Where(x => x.PhoneNumber == _phoneNumber).FirstOrDefault();
if (user != null)
{
try
{
var verifyId = await SecretSantaService.StartVeriy(_phoneNumber);
user.RequestId = verifyId;
await Database.SaveChangesAsync();
NavigationManager.NavigateTo($"/confirmCode/{verifyId}");
}
catch (VonageVerifyResponseException ex)
{
if (ex.Response.Status == "10")
{
NavigationManager.NavigateTo($"/confirmCode/{user.RequestId}");
}
}
}
else
{
_numberExists = false;
}
}
}
Ajouter une page d'enregistrement
Nous voulons permettre aux nouveaux utilisateurs d'enregistrer leur numéro de téléphone dans l'application. Pour ce faire, créez un nouveau fichier RegistrationPage.razor et ajoutez-y le formulaire suivant :
@inject SecretSantaContext dbContext;
@inject SecretSantaService SecretSantaService
@inject NavigationManager NavigationManager
@inject Microsoft.Extensions.Configuration.IConfiguration Config
@using Vonage.Verify
@page "/registration"
<h3>Register</h3>
<div class="row">
<div class="col-md-4">
<EditForm Model="@participant" OnValidSubmit="CreateUser">
<DataAnnotationsValidator />
<ValidationSummary />
Your Phone Number*:<br /><InputText id="phone" @bind-Value="participant.PhoneNumber" /><br />
Your Name*:<br /><InputText id="Name" @bind-Value="participant.Name" /><br />
Your Mailing Address*:<br /><InputText id="Address" @bind-Value="participant.Address" /><br />
Gift ideas (For You!):<br /><InputText id="GiftIdeas" @bind-Value="participant.GiftIdeas" /><br />
<button type="submit">Register</button>
<p>*Required fields</p>
</EditForm>
</div>
</div>
@if (_userExistsAlready == true)
{
<p>User exists already try <a href="/">logging in</a></p>
}
@if (!string.IsNullOrEmpty(_error))
{
<p><b>Error Encountered:</b> @_error</p>
}Ensuite, nous ajouterons une méthode de création d'utilisateur pour vérifier dans la base de données si l'utilisateur proposé existe déjà. Si ce n'est pas le cas, elle insérera l'utilisateur et lancera un événement de vérification. Dans le cas contraire, elle vous indiquera que la création a échoué parce que l'utilisateur existe déjà. J'ai également un numéro de téléphone d'administrateur pour lequel je vais configurer l'application ; ce numéro de téléphone déterminera qui est l'administrateur du jeu. Lorsqu'ils sont enregistrés, leur rôle est admin.
@code {
private SecretSantaParticipant participant = new SecretSantaParticipant();
private bool? _userExistsAlready;
private string _error = "";
private async Task CreateUser()
{
participant.PhoneNumber = participant.PhoneNumber.Replace("(", "");
participant.PhoneNumber = participant.PhoneNumber.Replace(")", "");
participant.PhoneNumber = participant.PhoneNumber.Replace("-", "");
if (!participant.PhoneNumber.StartsWith("1"))
{
participant.PhoneNumber = "1" + participant.PhoneNumber;
}
var userExists = dbContext.Participants.Where(x => x.PhoneNumber == participant.PhoneNumber).Any();
if (!userExists)
{
try
{
if (participant.PhoneNumber == Config["ADMIN_NUMBER"])
{
participant.Role = "admin";
}
else
{
participant.Role = "user";
}
var verifyRequestId = await SecretSantaService.StartVeriy(participant.PhoneNumber);
participant.RequestId = verifyRequestId;
dbContext.Participants.Add(participant);
dbContext.SaveChanges();
NavigationManager.NavigateTo($"/confirmCode/{verifyRequestId}");
}
catch (VonageVerifyResponseException ex)
{
_error = ex.Response.ErrorText;
}
}
else
{
_userExistsAlready = true;
}
}
}
Finalisation de la connexion
Lorsque quelqu'un crée un Account ou essaie de se connecter, nous devons le renvoyer vers une page où il pourra valider qu'il a le bon code. Vous remarquerez qu'après avoir envoyé la requête Verify, la fonction NavigationManager dirige l'utilisateur vers une nouvelle URL : NavigationManager.NavigateTo($"/confirmCode/{verifyRequestId}"); - cette action ouvrira une nouvelle page. Créez un nouveau composant Razor appelé CodeConfirmationPage.razor. Cette page prendra un paramètre à travers le chemin - l'ID de vérification, qui tentera finalement de confirmer le code. Cette page aura une simple boîte de saisie et un bouton pour nous permettre d'essayer la confirmation. Si l'authentification réussit, nous reviendrons à la page racine, qui sera désormais en mesure d'accéder au reste de l'application.
@using Microsoft.AspNetCore.Identity
@inject SecretSantaService VonageService
@inject SecretSantaContext db
@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider Provider
@page "/confirmCode/{VerifyRequestId}"
<h3>Confirm Code!</h3>
<input class="input-group-text" @bind="_code" />
<button class="btn-group-lg" @onclick="CheckCode">Confirm</button>
@if (_authenticated == false)
{
<p>Authentication Successful</p>
}
@code {
[Parameter]
public string VerifyRequestId { get; set; }
private string _code;
private bool? _authenticated;
private async Task CheckCode()
{
_authenticated = await VonageService.ConfirmCode(VerifyRequestId, _code);
if (_authenticated == true)
{
var user = db.Participants.Where(x => x.RequestId == VerifyRequestId).FirstOrDefault();
((AuthProvider)Provider).AuthorizeUser(user);
NavigationManager.NavigateTo("/");
}
}
}
Page Account
La dernière page que nous devons ajouter est la page de l'Account. Cette page aura un niveau d'accès différent selon que l'utilisateur est un administrateur ou non. Lorsque le jeu commencera, l'administrateur pourra vérifier que tout le monde est bien inscrit et pourra envoyer un message à tout le monde pour l'informer que le jeu a commencé.
Dans la partie affichage de cette page, nous montrerons à chacun son nom et les informations de son Account, ainsi que la personne avec laquelle il a été jumelé (en supposant qu'un jumelage ne soit pas encore en cours). Nous laisserons également les champs adresse et idée de cadeau modifiables, de sorte que si quelqu'un choisit de les mettre à jour, nous pourrons le faire. Créez un fichier razor appelé AccountComponent.razor et ajoutez les éléments suivants :
@inject SecretSantaContext Db
@inject AuthenticationStateProvider Provider
@inject NavigationManager NavigationManager
@inject SecretSantaService SecretSantaService
@using System.Security.Claims
<h3>Accounts</h3>
<table class="table-bordered">
<tr>
<th>Your Name</th>
<td>@participant.Name</td>
</tr>
<tr>
<th>Your Address</th>
<td><input class="input-group" @bind="participant.Address" /></td>
</tr>
<tr>
<th>Gift Ideas For You</th>
<td><input class="input-group" @bind="participant.GiftIdeas" /></td>
</tr>
@if (participant.Match != null)
{
<tr>
<th>Your Secret Santa</th>
<td>@participant.Match.Name</td>
</tr>
<tr>
<th>Gift Ideas</th>
<td>@participant.Match.GiftIdeas</td>
</tr>
<tr>
<th>Your Secret Santa's Address</th>
<td>@participant.Match.Address</td>
</tr>
}
else
{
<tr>
<th>Status</th>
<td>Pending match</td>
</tr>
}
</table>
@if (_isAdmin)
{
<h3>Admin Section</h3>
<table class="table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Phone Number</th>
<th>Address</th>
<th>Gift ideas</th>
<th>Matched?</th>
</tr>
</thead>
@foreach (var par in _participants)
{
<tr>
<td>@par.Name</td>
<td>@par.PhoneNumber</td>
<td>@par.Address</td>
<td>@par.GiftIdeas</td>
<td>@(par.Match!=null)</td>
</tr>
}
</table>
<button @onclick="Shuffle" class="btn-group-lg">Shuffle And Send</button>
<button @onclick="SecretSantaService.NotifyUsers">Notify Participants</button>
<br />
}
<p>@msg</p>
<button style="cursor:pointer" @onclick="UpdateAccount">Update Account</button>
<a @onclick="Logout" href="">Log Out</a>
En ce qui concerne le code, nous aurons une méthode pour initialiser la page pour nous. Supposons que l'identité de notre état d'authentification soit un administrateur. Dans ce cas, nous allons également interroger la base de données pour obtenir la liste des participants actuels au jeu et les afficher dans un tableau séparé. Nous aurons un bouton pour mélanger les utilisateurs et leur attribuer un Père Noël secret, puis nous aurons le bouton de l'administrateur pour lancer le concours, ce qui permettra au Père Noël d'envoyer le message d'accueil à tout le monde.
@code {
SecretSantaParticipant participant = new SecretSantaParticipant();
List<SecretSantaParticipant> _participants = new List<SecretSantaParticipant>();
string msg;
bool _isAdmin;
protected override async Task OnInitializedAsync()
{
var user = (await ((AuthProvider)Provider).GetAuthenticationStateAsync()).User.Claims.First(x => x.Type == ClaimTypes.Name).Value;
participant = Db.Participants.ToList().FirstOrDefault(x => x.PhoneNumber == user);
_isAdmin = participant.Role == "admin";
if (_isAdmin)
{
_participants = Db.Participants.ToList();
}
StateHasChanged();
}
private async void Shuffle()
{
await SecretSantaService.ShuffleUsers();
}
private void Logout()
{
((AuthProvider)Provider).LogOutUser();
}
private async void UpdateAccount()
{
var par = Db.Participants.FirstOrDefault(x => x.PhoneNumber == participant.PhoneNumber);
par = participant;
await Db.SaveChangesAsync();
msg = "Account Updated";
try
{
await SecretSantaService.NotifyUserOfUpdate(par);
}
catch (Exception ex) { msg = ex.Message; }
StateHasChanged();
}
} Configurer les itinéraires dans l'index
La dernière chose à faire pour configurer l'application est de remplacer le contenu du fichier Index.razor par un fichier AuthorizeViewqui affichera la page Account si l'état Auth est autorisé, et la page de connexion dans le cas contraire. Dans le fichier index.razor, ajoutez ce qui suit :
@page "/"
<AuthorizeView>
<Authorized>
<AccountComponent></AccountComponent>
</Authorized>
<NotAuthorized>
<Login></Login>
</NotAuthorized>
</AuthorizeView>
Configuration
Maintenant que nous avons écrit l'application, nous devons configurer la base de données et ajouter les variables d'environnement appropriées à l'application.
appsettings.json
Ouvrez votre fichier appsettings.json et ajoutez-y les clés suivantes :
"CONNECTION_STRING": "Host=localhost;Database=secretsantausers;User Id=username;Password=password;Port=5432",
"API_KEY": "API_KEY",
"API_SECRET": "API_SECRET",
"VONAGE_NUMBER": "VONAGE_NUMBER"Régler les API_KEY et API_SECRET avec votre clé API et votre secret à partir de votre tableau de bord Vonage. Réglez l'option VONAGE_NUMBER à l'un de vos numéros virtuels de Vonage. Réglez le numéro d'administrateur sur le numéro de téléphone portable de la personne qui sera l'administrateur du jeu (probablement vous-même). Enfin, définissez le CONNECTION_STRING à la chaîne de connexion de votre base de données.
Migrer la base de données
Enfin, nous devons migrer la base de données. Pour ce faire, vous aurez besoin de l'outil entity framework :
Lancez ensuite l'outil fluent pour créer la migration :
Enfin, lancez l'outil de mise à jour à partir de fluent pour appliquer toutes les migrations appropriées :
Conclusion
Et le tour est joué ! Vous pouvez maintenant lancer l'application en appuyant sur le bouton play dans IIS Express ou avec la commande dotnet run depuis votre terminal. Quoi qu'il en soit, vous êtes prêt !
Autres ressources
Une présentation complète de l'API Verify est disponible sur notre site web de documentation.
Vous pouvez voir d'autres utilisations de notre API SMS ici
Tout le code source de cette démo se trouve sur GitHub
