I want to my button “Votar” insert data of vote in table of my database “Votes”, but when i click in the button nothing happens, doesn’t show any error or something like this.
My structure of code are there, can we help me?
DBLayer
namespace ESOF.WebApp.DBLayer.Context;
using ESOF.WebApp.DBLayer.Entities;
using Microsoft.EntityFrameworkCore;
public partial class ApplicationDbContext{
private void BuildGames(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Game>()
.HasKey(g => g.GameId);
modelBuilder.Entity<Game>()
.Property(g => g.GameId)
.HasDefaultValueSql("gen_random_uuid()");
modelBuilder.Entity<Game>()
.Property(g => g.Name)
.IsRequired();
modelBuilder.Entity<Game>()
.Property(g => g.Description)
.IsRequired();
}
}
using ESOF.WebApp.DBLayer.Entities;
using Microsoft.EntityFrameworkCore;
// ReSharper disable once CheckNamespace
namespace ESOF.WebApp.DBLayer.Context;
public partial class ApplicationDbContext
{
private void BuildPermissions(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Permission>()
.HasMany(p => p.RolePermissions)
.WithOne(rp => rp.Permission)
.HasForeignKey(rp => rp.PermissionId);
modelBuilder.Entity<Permission>()
.Property(p => p.PermissionId)
.HasDefaultValueSql("gen_random_uuid()");
}
}
using ESOF.WebApp.DBLayer.Entities;
using Microsoft.EntityFrameworkCore;
// ReSharper disable once CheckNamespace
namespace ESOF.WebApp.DBLayer.Context;
public partial class ApplicationDbContext
{
private void BuildRolePermissions(ModelBuilder modelBuilder)
{
modelBuilder.Entity<RolePermission>()
.HasKey(e => new { e.RoleId, e.PermissionId });
}
}
using ESOF.WebApp.DBLayer.Entities;
using Microsoft.EntityFrameworkCore;
// ReSharper disable once CheckNamespace
namespace ESOF.WebApp.DBLayer.Context;
public partial class ApplicationDbContext
{
private void BuildRoles(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Role>()
.HasMany(r => r.UserRoles)
.WithOne(ur => ur.Role)
.HasForeignKey(ur => ur.RoleId);
modelBuilder.Entity<Role>()
.HasMany(r => r.RolePermissions)
.WithOne(rp => rp.Role)
.HasForeignKey(rp => rp.RoleId);
modelBuilder.Entity<Role>()
.Property(p => p.RoleId)
.HasDefaultValueSql("gen_random_uuid()");
}
}
using ESOF.WebApp.DBLayer.Entities;
using Microsoft.EntityFrameworkCore;
// ReSharper disable once CheckNamespace
namespace ESOF.WebApp.DBLayer.Context;
public partial class ApplicationDbContext
{
private void BuildUserRoles(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserRole>()
.HasKey(e => new { e.RoleId, e.UserId });
}
}
using ESOF.WebApp.DBLayer.Entities;
using Microsoft.EntityFrameworkCore;
// ReSharper disable once CheckNamespace
namespace ESOF.WebApp.DBLayer.Context;
public partial class ApplicationDbContext
{
private void BuildUsers(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany(u => u.UserRoles)
.WithOne(ur => ur.User)
.HasForeignKey(ur => ur.UserId);
modelBuilder.Entity<User>()
.HasIndex(u => u.Email)
.IsUnique();
modelBuilder.Entity<User>()
.Property(p => p.UserId)
.HasDefaultValueSql("gen_random_uuid()");
}
}
using ESOF.WebApp.DBLayer.Entities;
using Microsoft.EntityFrameworkCore;
namespace ESOF.WebApp.DBLayer.Context;
public partial class ApplicationDbContext{
private void BuildVotes(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Vote>()
.HasKey(e => e.VoteId);
modelBuilder.Entity<Vote>()
.Property(v => v.VoteId)
.HasDefaultValueSql("gen_random_uuid()");
modelBuilder.Entity<Vote>()
.Property(v => v.VoteTime)
.IsRequired();
modelBuilder.Entity<Vote>()
.Property(v => v.UserId)
.IsRequired();
modelBuilder.Entity<Vote>()
.Property(v => v.GameId)
.IsRequired();
modelBuilder.Entity<Vote>()
.HasOne(e => e.User)
.WithMany(u => u.Votes)
.HasForeignKey(e => e.UserId)
.HasConstraintName("id_user__fk");
modelBuilder.Entity<Vote>()
.HasOne(e => e.Game)
.WithMany(g => g.Votes)
.HasForeignKey(e => e.GameId)
.HasConstraintName("id_game__fk");
}
}
using DotNetEnv;
using ESOF.WebApp.DBLayer.Entities;
using Helpers;
using Microsoft.EntityFrameworkCore;
namespace ESOF.WebApp.DBLayer.Context;
public partial class ApplicationDbContext : DbContext
{
private static readonly DbContextOptions DefaultOptions = new Func<DbContextOptions>(() =>
{
var optionsBuilder = new DbContextOptionsBuilder();
var db = EnvFileHelper.GetString("POSTGRES_DB");
var user = EnvFileHelper.GetString("POSTGRES_USER");
var password = EnvFileHelper.GetString("POSTGRES_PASSWORD");
var port = EnvFileHelper.GetString("POSTGRES_PORT");
var host = EnvFileHelper.GetString("POSTGRES_HOST");
if (string.IsNullOrEmpty(db) || string.IsNullOrEmpty(user) || string.IsNullOrEmpty(password) ||
string.IsNullOrEmpty(port) || string.IsNullOrEmpty(host))
{
throw new InvalidOperationException(
"Database connection information not fully specified in environment variables.");
}
var connectionString = $"Host={host};Port={port};Database={db};Username={user};Password={password}";
optionsBuilder.UseNpgsql(connectionString);
return optionsBuilder.Options;
})();
public ApplicationDbContext()
: base(DefaultOptions)
{
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Permission> Permissions { get; set; }
public DbSet<UserRole> UserRoles { get; set; }
public DbSet<RolePermission> RolePermissions { get; set; }
public DbSet<Game> Games { get; set; }
public DbSet<Vote> Votes { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
BuildUsers(modelBuilder);
BuildRoles(modelBuilder);
BuildPermissions(modelBuilder);
BuildRolePermissions(modelBuilder);
BuildUserRoles(modelBuilder);
BuildGames(modelBuilder);
BuildVotes(modelBuilder);
base.OnModelCreating(modelBuilder);
}
}
using System.ComponentModel.DataAnnotations;
namespace ESOF.WebApp.DBLayer.Entities;
public class Game{
[Key]
public Guid GameId{ get; set; }
[Required]
public String Name{ get; set; }
[Required]
public String Description{ get; set; }
public ICollection<Vote> Votes { get; set; }
}
using System.ComponentModel.DataAnnotations;
namespace ESOF.WebApp.DBLayer.Entities;
public class Permission
{
[Key]
public Guid PermissionId { get; set; }
[Required]
public string Name { get; set; }
public ICollection<RolePermission> RolePermissions { get; set; }
}
using System.ComponentModel.DataAnnotations;
namespace ESOF.WebApp.DBLayer.Entities;
public class Role
{
[Key]
public Guid RoleId { get; set; }
[Required]
public string Name { get; set; }
public ICollection<UserRole> UserRoles { get; set; }
public ICollection<RolePermission> RolePermissions { get; set; }
}
using System.ComponentModel.DataAnnotations;
namespace ESOF.WebApp.DBLayer.Entities;
public class RolePermission
{
public Guid RoleId { get; set; }
public Guid PermissionId { get; set; }
public Role Role { get; set; }
public Permission Permission { get; set; }
}
using System.ComponentModel.DataAnnotations;
namespace ESOF.WebApp.DBLayer.Entities;
public class User
{
[Key]
public Guid UserId { get; set; }
[EmailAddress, Required]
public string Email { get; set; }
[Required]
public byte[] PasswordHash { get; set; }
[Required]
public byte[] PasswordSalt { get; set; }
public ICollection<UserRole> UserRoles { get; set; }
public ICollection<Vote> Votes { get; set; }
}
namespace ESOF.WebApp.DBLayer.Entities;
public class UserRole
{
public Guid UserId { get; set; }
public User User { get; set; }
public Guid RoleId { get; set; }
public Role Role { get; set; }
}
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ESOF.WebApp.DBLayer.Entities;
public class Vote
{
[Key]
public Guid VoteId { get; set; }
[Required]
public Guid UserId { get; set; }
[ForeignKey(nameof(UserId))]
public User User { get; set; }
[Required]
public Guid GameId { get; set; }
[ForeignKey(nameof(GameId))]
public Game Game { get; set; }
[Required]
public DateTime VoteTime { get; set; }
}
Frontend
@page "/gameofthemonth"
@using ESOF.WebApp.DBLayer.Entities
@inject HttpClient Http
<h3>Vote no Jogo do Mês</h3>
@if (games == null)
{
<p>Carregando...</p>
}
else if (!games.Any())
{
<p>Nenhum jogo encontrado.</p>
}
else
{
<ul>
@foreach (var game in games)
{
<li>
<b>@game.Name</b> - @game.Description
<button @onclick="@(async () => await VoteForGame(userId, game.GameId))" disabled="@hasVoted">Votar</button>
@if (votePercentages.TryGetValue(game.GameId, out var percentage))
{
<span>(@percentage%)</span>
}
</li>
}
</ul>
}
<p>@message</p>
@code {
private List<Game>? games;
private string? message;
private Guid userId = Guid.NewGuid();
private bool hasVoted = false;
private Dictionary<Guid, double> votePercentages = new();
private bool isVotingPeriod = false;
protected override async Task OnInitializedAsync()
{
try
{
games = await Http.GetFromJsonAsync<List<Game>>("api/game");
hasVoted = await CheckIfUserHasVoted();
isVotingPeriod = IsVotingPeriod();
if (games == null)
{
message = "Nenhum jogo foi retornado da API.";
}
else
{
await UpdateVotePercentages();
}
}
catch (Exception ex)
{
message = "Erro ao carregar os jogos: " + ex.Message;
}
}
private bool IsVotingPeriod()
{
var today = DateTime.Now;
var lastDayOfMonth = new DateTime(today.Year, today.Month, DateTime.DaysInMonth(today.Year, today.Month));
var firstVotingDay = lastDayOfMonth.AddDays(-4);
return today >= firstVotingDay;
}
private async Task<bool> CheckIfUserHasVoted()
{
return await Http.GetFromJsonAsync<bool>($"api/vote/HasVoted/{userId}");
}
private async Task VoteForGame(Guid userId, Guid gameId)
{
if (!isVotingPeriod)
{
message = "A votação só está disponível nos últimos 5 dias do mês.";
return;
}
try
{
if (await CheckIfUserHasVoted())
{
message = "Você já votou neste mês.";
return;
}
var vote = new Vote { UserId = userId, GameId = gameId, VoteTime = DateTime.Now };
var response = await Http.PostAsJsonAsync("api/vote", vote);
if (response.IsSuccessStatusCode)
{
message = "Voto registrado com sucesso!";
hasVoted = true;
await UpdateVotePercentages();
}
else
{
var errorContent = await response.Content.ReadAsStringAsync();
message = errorContent.Contains("Já votou este mês.") ? "Já votou este mês." : "Erro ao registrar voto.";
}
}
catch (Exception ex)
{
message = "Erro ao tentar registrar o voto: " + ex.Message;
}
StateHasChanged();
}
private async Task UpdateVotePercentages()
{
var voteCounts = await Http.GetFromJsonAsync<Dictionary<Guid, int>>("api/vote/Counts");
if (voteCounts != null)
{
var totalVotes = voteCounts.Values.Sum();
foreach (var game in games)
{
votePercentages[game.GameId] = voteCounts.TryGetValue(game.GameId, out var count) ? (double)count / totalVotes * 100 : 0;
}
}
}
}
@page "/votes"
@inject HttpClient Http
@using ESOF.WebApp.DBLayer.Entities
<h3>Jogo do Mês</h3>
@if (gameOfTheMonth != null)
{
<div>
<b>@gameOfTheMonth.Name</b>
<p>@gameOfTheMonth.Description</p>
</div>
}
else
{
<p>Nenhum jogo foi selecionado este mês.</p>
}
@code {
private Game? gameOfTheMonth;
protected override async Task OnInitializedAsync()
{
try
{
gameOfTheMonth = await Http.GetFromJsonAsync<Game>("api/vote/GameOfTheMonth");
}
catch (Exception ex)
{
Console.WriteLine("Erro ao carregar o jogo do mês: " + ex.Message);
}
}
}
namespace Frontend.Helpers;
public class ApiHelper(HttpClient httpClient)
{
public async Task<T?> GetFromApiAsync<T>(string url)
{
try
{
var response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<T>();
}
catch (HttpRequestException e)
{
// Handle exception
throw new ApplicationException($"Error fetching data from {url}: {e.Message}");
}
}
}
using ESOF.WebApp.DBLayer.Entities;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace Frontend.Services
{
public class VoteService
{
private readonly HttpClient _httpClient;
public VoteService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<List<Game>> GetGamesAsync()
{
return await _httpClient.GetFromJsonAsync<List<Game>>("api/game");
}
public async Task<bool> HasUserVotedAsync(Guid userId)
{
return await _httpClient.GetFromJsonAsync<bool>($"api/vote/HasVoted/{userId}");
}
public async Task<HttpResponseMessage> VoteForGameAsync(Vote vote)
{
return await _httpClient.PostAsJsonAsync("api/vote", vote);
}
public async Task<Dictionary<Guid, int>> GetVoteCountsAsync()
{
return await _httpClient.GetFromJsonAsync<Dictionary<Guid, int>>("api/vote/Counts");
}
}
}
WebAPI
using Microsoft.AspNetCore.Mvc;
using ESOF.WebApp.DBLayer.Entities;
using ESOF.WebApp.DBLayer.Context;
using Microsoft.EntityFrameworkCore;
[Route("api/[controller]")]
[ApiController]
public class GameController : ControllerBase
{
private readonly ApplicationDbContext _context;
public GameController(ApplicationDbContext context)
{
_context = context;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Game>>> GetGames()
{
try
{
var games = await _context.Games.ToListAsync();
return Ok(games);
}
catch (Exception ex)
{
// Log exception
Console.WriteLine($"Erro ao buscar jogos: {ex.Message}");
return StatusCode(500, "Erro interno no servidor.");
}
}
[HttpGet("{id}")]
public async Task<ActionResult<Game>> GetGame(Guid id)
{
try
{
var game = await _context.Games.FindAsync(id);
if (game == null)
{
return NotFound();
}
return game;
}
catch (Exception ex)
{
// Log exception
Console.WriteLine($"Erro ao procurar jogo: {ex.Message}");
return StatusCode(500, "Erro interno no servidor.");
}
}
}
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using System.Threading.Tasks;
using ESOF.WebApp.DBLayer.Context;
using ESOF.WebApp.DBLayer.Entities;
using Microsoft.EntityFrameworkCore;
[Route("api/[controller]")]
[ApiController]
public class VoteController : ControllerBase
{
private readonly ApplicationDbContext _context;
public VoteController(ApplicationDbContext context)
{
_context = context;
}
[HttpPost]
public async Task<IActionResult> Vote([FromBody] Vote vote)
{
var today = DateTime.Now;
var lastDayOfMonth = new DateTime(today.Year, today.Month, DateTime.DaysInMonth(today.Year, today.Month));
var firstVotingDay = lastDayOfMonth.AddDays(-4);
if (today < firstVotingDay)
{
return BadRequest("A votação só está disponível nos últimos 5 dias do mês.");
}
try
{
var existingVote = await _context.Votes
.FirstOrDefaultAsync(v => v.UserId == vote.UserId &&
v.VoteTime.Month == today.Month &&
v.VoteTime.Year == today.Year);
if (existingVote != null)
{
return BadRequest("Você já votou este mês.");
}
vote.VoteTime = today;
_context.Votes.Add(vote);
await _context.SaveChangesAsync();
return Ok();
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao registrar voto: {ex.Message}");
return StatusCode(500, "Erro interno no servidor.");
}
}
[HttpGet("GameOfTheMonth")]
public async Task<ActionResult<Game>> GetGameOfTheMonth()
{
try
{
var gameOfTheMonthId = await _context.Votes
.Where(v => v.VoteTime.Month == DateTime.Now.Month && v.VoteTime.Year == DateTime.Now.Year)
.GroupBy(v => v.GameId)
.OrderByDescending(g => g.Count())
.Select(g => g.Key)
.FirstOrDefaultAsync();
if (gameOfTheMonthId == default)
{
return NotFound("Nenhum voto foi registado este mês.");
}
var game = await _context.Games.FindAsync(gameOfTheMonthId);
return Ok(game);
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao procurar jogo do mês: {ex.Message}");
return StatusCode(500, "Erro interno no servidor.");
}
}
[HttpGet("HasVoted/{userId}")]
public async Task<ActionResult<bool>> HasVoted(Guid userId)
{
var existingVote = await _context.Votes
.AnyAsync(v => v.UserId == userId && v.VoteTime.Month == DateTime.Now.Month && v.VoteTime.Year == DateTime.Now.Year);
return Ok(existingVote);
}
[HttpGet("Counts")]
public async Task<ActionResult<Dictionary<Guid, int>>> GetVoteCounts()
{
var voteCounts = await _context.Votes
.Where(v => v.VoteTime.Month == DateTime.Now.Month && v.VoteTime.Year == DateTime.Now.Year)
.GroupBy(v => v.GameId)
.Select(g => new { GameId = g.Key, Count = g.Count() })
.ToDictionaryAsync(g => g.GameId, g => g.Count);
return Ok(voteCounts);
}
}
using ESOF.WebApp.DBLayer.Entities;
using ESOF.WebApp.DBLayer.Context;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ESOF.WebApp.WebAPI.Services
{
public class VoteService
{
private readonly ApplicationDbContext _context;
public VoteService(ApplicationDbContext context)
{
_context = context;
}
public async Task<List<Game>> GetGamesAsync()
{
return await _context.Games.ToListAsync();
}
private async Task<bool> HasUserVotedAsync(Guid userId, int month, int year)
{
return await _context.Votes
.AnyAsync(v => v.UserId == userId && v.VoteTime.Month == month && v.VoteTime.Year == year);
}
public async Task<bool> VoteForGameAsync(Vote vote)
{
// Verifica se o usuário já votou neste mês (se necessário)
var hasVoted = await HasUserVotedAsync(vote.UserId, vote.VoteTime.Month, vote.VoteTime.Year);
if (hasVoted)
{
return false; // Ou lance uma exceção informando que o usuário já votou
}
_context.Votes.Add(vote);
var result = await _context.SaveChangesAsync() > 0;
return result;
}
public async Task<Dictionary<Guid, int>> GetVoteCountsAsync()
{
return await _context.Votes
.GroupBy(v => v.GameId)
.Select(g => new { GameId = g.Key, Count = g.Count() })
.ToDictionaryAsync(g => g.GameId, g => g.Count);
}
public async Task<Dictionary<Guid, double>> GetVotePercentagesAsync()
{
var totalVotes = await _context.Votes.CountAsync();
if (totalVotes == 0) return new Dictionary<Guid, double>();
return await _context.Votes
.GroupBy(v => v.GameId)
.Select(g => new { GameId = g.Key, Percentage = (double)g.Count() / totalVotes * 100 })
.ToDictionaryAsync(g => g.GameId, g => g.Percentage);
}
public async Task<Game?> GetGameOfTheMonthAsync()
{
var gameOfTheMonthId = await _context.Votes
.Where(v => v.VoteTime.Month == DateTime.Now.Month && v.VoteTime.Year == DateTime.Now.Year)
.GroupBy(v => v.GameId)
.OrderByDescending(g => g.Count())
.Select(g => g.Key)
.FirstOrDefaultAsync();
if (gameOfTheMonthId == Guid.Empty)
{
return null;
}
var game = await _context.Games.FindAsync(gameOfTheMonthId);
return game;
}
}
}
After that code i need make polls with all games, the game what have bigger number of votes will be Game of The Month, the poll will open in the last 5 days of the month and refresh the game of the month in day 1 of the next month.
Can we help me?
After that code i need make polls with all games, the game what have bigger number of votes will be Game of The Month, the poll will open in the last 5 days of the month and refresh the game of the month in day 1 of the next month.
Can we help me?
Faria13 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.