
Compartir:
Antiguo desarrollador .NET Advocate @Vonage, ingeniero de software poliglota full-stack, AI/ML
Crea una aplicación de amigo invisible con Blazor
Tiempo de lectura: 14 minutos
El Adviento es una época de expectación. Por supuesto, hay una anticipación espiritual fundamental que muchos de nosotros sentimos en el período previo a la Navidad. También está la anticipación de tiempo libre para relajarnos y regocijarnos con nuestras familias en nuestras tradiciones.
En el espíritu de Adviento Cpermítanme compartir cómo mi familia mantendrá sus tradiciones en estos tiempos difíciles. Este año he creado una aplicación Blazor para virtualizar nuestro juego anual del amigo invisible. Permite que los participantes se registren con su número de teléfono y les envía un mensaje con el que deben enviar un regalo.
El problema
Todos los años hacemos un intercambio de regalos de amigo invisible. Mi mujer se pone en contacto con todos los miembros de la familia para ver quién quiere participar. El número varía en función de la participación de los más jóvenes. Lo normal es que al final haya unos quince participantes.
A continuación, Theresa compra tarjetas para cada participante y rellena las reglas del juego. Por ejemplo, no gastar más de $xx. Después mete todas las tarjetas en sobres y, en Acción de Gracias (el cuarto jueves de noviembre), nos reunimos para repartirlas.
Cada año nos encontramos con un problema, invariablemente un par de participantes no están presentes en la cena de Acción de Gracias, nuestra familia se distribuye uniformemente entre Nueva York, Nueva Jersey y Florida. Esto crea un problema práctico ya que no podemos asignar al azar a alguien que no está presente un amigo invisible, ya que potencialmente podrían conseguirse a sí mismos. En el pasado, siempre hemos podido solucionar este problema haciendo que una persona, que no participa, seleccione a cualquiera que no esté presente para asegurarse de que no se recibe a sí mismo. Después, mi mujer dirige todos los sobres a las personas correspondientes y los envía.
Este año, en lugar de faltar una o dos personas, nos faltaban una docena, y sin nadie presente para arbitrar el proceso de selección y garantizar que nadie se quedara solo, tuvimos que ser creativos.
Ir directamente al código
Si quieres saltarte este tutorial y quieres ejecutar tu propio juego del amigo invisible, todo el código está disponible en GitHub
Requisitos previos
Necesitará el último SDK DE .NET
Yo uso Visual Studio 2019 para esta demo. Si lo desea, puede utilizar VS Code
Voy a utilizar Postgres para esta demostración. Asumiré para los propósitos de esta demostración que tienes el servidor instalado. Puedes usar cualquier base de datos que desees, siempre y cuando actualices el contexto de la base de datos para ella
He desplegado esto a Azure - si usted decide hacerlo, eso depende de usted, pero para ejecutar esto, sólo necesita IIS Express o
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.
Crear el proyecto
Nuestro primer paso va a ser crear nuestro proyecto. Navega a tu directorio de desarrollo, y ejecuta el siguiente comando en tu terminal:
dotnet new blazorserver --no-https -n SecretSantaEste comando creará una carpeta y un proyecto llamados SecretSanta. ejecutar cd SecretSanta para navegar dentro de este directorio y luego ejecutar los siguientes comandos:
dotnet add package Vonage
dotnet add package Microsoft.AspNetCore.Components.Authorization
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL Construir el modelo de datos
Vamos a utilizar Entity Framework Core para manejar todos nuestros datos. Como he mencionado antes, estoy usando Postgres para esto, pero no hay ninguna necesidad general de utilizar Postgres. Puedes usar cualquier base de datos que te haga sentir cómodo.
Crea un archivo llamado SecretSantaParticipant. y añádele lo siguiente:
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; }
}Esta clase será el modelo de datos que pasaremos entre nuestro cliente y el servidor para gestionar las Account del Amigo Invisible.
Crear contexto de base de datos
Cree un archivo llamado SecretSantaContext.cs. Haga que la clase SecretSantaContext clase extend DbContext y añádele lo siguiente
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"]);Nota: Aquí es donde debe realizar los cambios para utilizar una base de datos diferente si lo desea.
Crear un proveedor de autenticación
Utilizaremos la Verify API de Vonage para manejar el inicio de sesión de nuestros usuarios. Tendremos un AuthenticationStateProvider que administrará el estado de inicio de sesión de nuestros usuarios. Crearemos un nuevo archivo AuthProvider.cs y haz que la clase AuthProvider clase extienda AuthenticationStateProvider.
En la clase AuthProvider añada un miembro privado ClaimsIdentiy privado llamado _identity:
private ClaimsIdentity _identity = new ClaimsIdentity();Estamos inicializando esta identidad de reclamaciones de forma anónima al principio para que el usuario no tenga reclamaciones cuando llegue por primera vez a nuestra página, lo que significa que tendrá que completar una secuencia de inicio de sesión.
Obtener estado de autenticación
A continuación, vamos a proporcionar un medio para obtener el estado de autenticación sobrecargando el método GetAuthenticationStateAsync . Este método devolverá un estado de autenticación con nuestra identidad.
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
return await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(_identity)));
} Actualizar estado de autenticación
Este proveedor de estado se asignará a la sesión de un usuario en particular y le dirá a nuestra aplicación a qué se le permite acceder en una página determinada. En consecuencia, necesitamos un medio para actualizar el estado de autenticación.
Para ello, añadiremos un método de inicio de sesión y otro de cierre de sesión. El método Login AuthorizeUser creará un nuevo ClaimsIdentity con el número de teléfono del usuario y su rol (si es un administrador, podrá ver más cosas). A continuación, notificará a cualquiera que vea el AuthProvider que el estado de autenticación ha cambiado:
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)));
}A la inversa, el método LogOutUser restablecerá el estado ClaimsIdentity a anonymous y notificará a todo lo que esté escuchando al proveedor de estado que actualizó el estado auth.
public void LogOutUser()
{
_identity = new ClaimsIdentity();
var user = new ClaimsPrincipal(_identity);
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));
} Crear un servicio de amigo invisible
Vamos a añadir un servicio inyectable de dependencia para permitirnos hacer todas las cosas de backend que nuestra aplicación necesita hacer. Este servicio incluye el manejo de la verificación, lectura y escritura de la base de datos, y el envío de mensajes a nuestros participantes. Crea un archivo llamado SecretSantaService.cs.
Vamos a inyectar tres cosas en nuestra dependencia SecretSantaService:
Nuestro
VonageClientque gestionará todas las solicitudes de la API de Vonage por nosotrosNuestro
SecretSantaContextque arbitrará todas nuestras conexiones a la base de datosUn objeto
IConfigurationque nos da acceso a la configuración de la aplicación
Decláralos como tales:
private readonly VonageClient _client;
private readonly SecretSantaContext _db;
private readonly IConfiguration _config;Y luego inyectarlos en nuestro servicio a través del constructor:
public SecretSantaService(VonageClient client, SecretSantaContext context, IConfiguration config)
{
_client = client;
_db = context;
_config = config;
} Crear una solicitud de Verify
Utilizaremos el número de teléfono del participante para verificar su acceso a la cuenta. Este método creará una especie de 1FA para el inicio de sesión. Yo no usaría 1FA bajo ninguna circunstancia en la que necesitara un inicio de sesión seguro, pero ya que esto es sólo un divertido juego familiar, y nuestro objetivo es verificar el número de teléfono, voy a dejarlo ahí.
Para iniciar la 1FA, agregaremos un método para iniciar la verificación y devolver el ID de inicio de Verify. Haremos esto con la Verify API de Vonage. En este punto, es solo una línea de código:
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;
} Confirmación del asa
Cuando un usuario ingresa su número para iniciar sesión o crea su cuenta, podemos solicitar a Vonage Verify API que complete una solicitud de verificación. Podemos hacer esto usando el método VerifyCheck en el cliente 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;
}
} Usuarios de Shuffle
El siguiente método barajará a los usuarios y distribuirá una asignación para el juego del amigo invisible. Este método revisará todos los usuarios que no tienen un amigo invisible asignado y les dará al azar una selección del grupo de usuarios que no tienen un amigo invisible Giver todavía.
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();
} Informar a los participantes
Ahora que los usuarios se han barajado, ¡hay que decirles a todos quién es su pareja!
Para ello, utilizaremos la API de SMS de Vonage. Haremos un bucle con nuestros participantes y les diremos quién es su amigo invisible, cuánto deben gastar y adónde deben enviar su regalo. Estoy haciendo esta parte con un LVN de Vonage, que tiene un límite de un mensaje por segundo. Por lo tanto, haré que la aplicación espere 1 segundo entre solicitudes. Como tenemos algunos participantes más jóvenes en este juego, ¡vamos a decirles que Papá Noel necesita su ayuda!
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);
}
} Enviar actualizaciones
Ahora no habrá mucho que un usuario pueda configurar después de haberse registrado, pero he decidido permitirles cambiar su dirección y las ideas que quieren dar a su amigo invisible para los regalos. En consecuencia, cuando un usuario entra y edita su Account, vamos a enviar un SMS al regalador informándole de la actualización:
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
});
}
} Configurar middleware
Estamos utilizando varias piezas de middleware para esto. Estamos utilizando el contexto de base de datos para mantener una conexión con nuestra base de datos. Usamos el objeto VonageClient para realizar solicitudes de API a Vonage, y estamos utilizando un objeto de configuración para extraer nuestro número de Vonage. Usamos nuestro AuthProvider para extraer nuestro estado de autorización.
Vamos a necesitar registrar todos estos servicios con nuestra aplicación. Para ello, entra en Startup.cs y busca el método ConfigureServices método Añádele lo siguiente:
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>();Con todos los servicios configurados, ahora tenemos que asegurarnos de habilitar Autenticación y Autorización para autorizar todo. Permanece en el archivo Startup.cs y ve al método Configure y añádele las dos líneas siguientes:
app.UseAuthorization();
app.UseAuthentication(); Construir el frontend
Con todo el backend resuelto, todo lo que queda es construir nuestro frontend. Dado que estamos utilizando un componente Authorization para propagar nuestro estado de autorización a todos los componentes, primero tendremos que envolver toda la aplicación en un componente CascadingAuthenticationState abre App.razor y rodear toda la aplicación con etiquetas <CascadingAuthenticationState></CascadingAuthenticationState> tags.
Añadir un componente de inicio de sesión
Añada un Login.razor bajo la carpeta /Pages aquí sólo vamos a añadir una entrada para manejar nuestro inicio de sesión y un botón para realizar el inicio de sesión así:
@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>
A continuación, vamos a añadir algo de lógica para realizar el inicio de sesión. Vamos a iniciar una solicitud de Verify, que enviará un código al usuario si la verificación no ha comenzado. De lo contrario, los dirigirá a la página de confirmación para introducir su 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;
}
}
}
Añadir página de registro
Queremos que los nuevos usuarios puedan registrar su número de teléfono en la aplicación. Para ello, cree un nuevo archivo RegistrationPage.razor y añádele el siguiente formulario:
@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>
}A continuación, añadiremos un método create user para comprobar en la base de datos si el usuario propuesto ya existe. Si no existe, insertará el usuario e iniciará un evento Verify. De lo contrario, le dirá que la creación falló porque el usuario ya existe. Además, tengo un número de teléfono de administrador para el que voy a configurar la aplicación; ese número de teléfono decidirá quién es el administrador del juego. Cuando se registran, su rol es 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;
}
}
}
Finalizar el inicio de sesión
Después de que alguien cree una Account o intente iniciar sesión, tenemos que reenviarle a una página en la que validará que tiene el código correcto. Verás que después de enviar la petición Verify, el comando NavigationManager redirige al usuario a una nueva URL: NavigationManager.NavigateTo($"/confirmCode/{verifyRequestId}"); - este acto abrirá una nueva página. Crea un nuevo componente Razor llamado CodeConfirmationPage.razor. Esta página tomará un parámetro a través de la ruta - el ID de verificación, que finalmente intentará la confirmación del código. Esta página tendrá una simple caja de entrada y un botón para que intentemos la confirmación. Si la autenticación tiene éxito, vamos a navegar de vuelta a la página raíz, que ahora será capaz de ruta para el resto de la aplicación.
@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("/");
}
}
}
Página de Account
La última página que necesitamos agregar es la página de Account. Ahora bien, esto en realidad tiene una diferencia en el nivel de acceso en función de si el usuario es un administrador o no. Cuando el juego está listo para comenzar, el administrador tendrá que validar que todo el mundo está correctamente, y tendrá la capacidad de enviar el mensaje a todo el mundo que el juego ha comenzado.
En la parte de visualización de esta página mostraremos a todo el mundo su nombre y la información de su Account, así como con quién están emparejados (suponiendo que aún no haya un emparejamiento pendiente). También dejaremos los campos de dirección e idea de regalo editables para que, si alguien decide actualizarlos, podamos hacerlo. Cree un archivo razor llamado AccountComponent.razor y añade lo siguiente:
@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>
Ahora en la parte de código de esto, tendremos un método para inicializar la página para nosotros. Supongamos que la identidad de nuestro estado de autenticación es un admin. En ese caso, también vamos a consultar la base de datos para obtener la lista de los participantes actuales en el juego y mostrarlos en una tabla separada. Tendremos un botón para barajar a los usuarios y asignarles un amigo invisible, y luego tendremos el botón del administrador para iniciar el concurso, que hará que Papá Noel envíe la felicitación a todo el mundo.
@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();
}
} Configurar las rutas en el índice
La última cosa relacionada con el código que tenemos que hacer para configurar la aplicación es sustituir el contenido del archivo Index.razor por un AuthorizeViewque mostrará la página de Account si el Auth sate está autorizado, y la página de login en caso contrario. En el archivo index.razor agrega lo siguiente:
@page "/"
<AuthorizeView>
<Authorized>
<AccountComponent></AccountComponent>
</Authorized>
<NotAuthorized>
<Login></Login>
</NotAuthorized>
</AuthorizeView>
Configuración
Ahora que hemos escrito la aplicación, tenemos que configurar la base de datos y añadir las variables de entorno adecuadas a la aplicación.
appsettings.json
Abra su appsettings.json y añádele las siguientes claves:
"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"Establezca el API_KEY y API_SECRET con tu clave y secreto de API desde tu Panel de Vonage. Configura el VONAGE_NUMBER a uno de tus números virtuales de Vonage. Establece el número de administrador en el número de teléfono móvil de quien quieras que sea el administrador del juego (presumiblemente tú mismo). Por último, establece el CONNECTION_STRING a la cadena de conexión de tu base de datos.
Migrar la base de datos
Por último, tendremos que migrar la base de datos. Para ello, vas a necesitar la herramienta entity framework:
A continuación, ejecute la herramienta fluent para crear la migración:
Por último, ejecute la herramienta de actualización desde fluent para aplicar todas las migraciones pertinentes:
Conclusión
Y ya está. Ahora puede ejecutar la aplicación pulsando el botón de reproducción en IIS Express o con el comando dotnet run desde tu terminal. En cualquier caso, ¡ya está todo listo!
Otros recursos
Encontrará una descripción completa de Verify API en nuestra sitio web de documentación.
Puedes ver más usos de nuestra SMS API aquí
Todo el código fuente de esta demo puede encontrarse en GitHub
