Blazor - Criando um Questionário on-line

Hoje vamos usar o Blazor para criar um questionário on-line onde veremos alguns dos recursos básicos do Blazor.

Se você esta chegando agora e não sabe o que é o Blazor leia o artigo ASP .NET Core - Iniciando com o Blazor - Macoratti; se você já conhece e quer saber mais pode fazer o curso de Blazor Essencial.  

Hoje teremos um questionário on-line para testar o conhecimento de Inglês. Nesta aplicação veremos alguns recursos básicos do Blazor como uso de componentes e o uso da linguagem C#.

Desta vez vamos criar uma aplicação do lado do servidor.

Recursos usados:

Criando o projeto Blazor no VS Community 2019

Abra o VS 2019 Community (versão mínima 16.3) e selecione a opção Create a New Project;

A seguir selecione a opção Blazor app e clique em next;

Informe o nome do projeto :  Blazor_Questionario, a localização e clique em Create;

A seguir teremos uma janela com duas opções :

  1. Blazor Server App
  2. Blazor WebAssembly App

Selecione a primeira opção - Blazor Server App. Não vamos usar autenticação nem habilitar o https.

A seguir clique no botão Create para criar o projeto.

Ao final teremos o projeto criado com a estrutura abaixo:

A pasta wwwroot é onde os recursos estáticos usados pela aplicação são colocados.

As pastas Pages e Shared são as mais importantes do projeto e contém componentes que são arquivos com a extensão .razor.

Na pasta Pages temos os componentes roteados, ou seja, que possuem uma rota definida usando a diretiva @page.

Na pasta Shared temos os componentes não roteados e que podem ser compartilhados com os demais componentes.

Na pasta Data é onde colocamos os dados que a aplicação vai usar.

O arquivo _Imports.razor é onde definimos os namespaces que poderão ser compartilhados com todos os componentes.

O arquivo App.razor é esta definindo o roteamento e o layout padrão usado no projeto.

No arquivo Startup.cs podemos configurar serviços e recursos da mesma forma que fazemos na ASP .NET Core.

Ajustando o projeto criado

Será criado um projeto padrão que vamos ajustar da seguinte forma:

  • Na pasta Pages vamos remover os arquivos FetchData.razor e Counter.razor;
  • Na pasta Shared vamos remover o arquivo SurveyPrompt.razor;

Na pasta wwwroot vamos criar a pasta images e nesta pasta vamos incluir a imagen que iremos usar em nosso projeto : teste1.jpg

No arquivo NavMenu, na pasta Shared, é onde definimos os links para o menu da aplicação. Vamos alterar o conteúdo deste arquivo conforme abaixo:

<div class="top-row pl-4 navbar navbar-dark">
    <a class="navbar-brand" href="">Blazor_Questionario</a>
    <button class="navbar-toggler" @onclick="ToggleNavMenu">
        <span class="navbar-toggler-icon"></span>
    </button>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-calculator" aria-hidden="true"></span> Home
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="teste">
                <span class="oi oi-book" aria-hidden="true"></span> Teste seu Inglês
            </NavLink>
        </li>
    </ul>
</div>
@code {
    bool collapseNavMenu = true;
    string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
    void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }

Alteramos o código do menu para exibir os links com os textos: Home e 'Teste seu Inglês'

Definindo o modelo de dados na pasta Data

Vamos criar o arquivo Questionario.cs na pasta Data onde vamos definir o modelo de dados que iremos usar no projeto.

public class Questionario
    {
        public string Pergunta { get; set; }
        public List<string> Opcoes { get; set; }
        public int RespostaIndex { get; set; }
        public int Placar { get; set; }
        public Questionario()
        {
            Opcoes = new List<string>();
        }
    }

Criamos a classe Questionario com os campos que iremos usar para exibir uma pergunta, as suas opções e definimos qual o indice da resposta e qual o placar acumulado.

Como não vamos usar um banco de dados vamos definir uma classe QuestionarioService onde vamos alimentar com dados a nossa classe Questionario :

using System.Collections.Generic;
using System.Threading.Tasks;

namespace Blazor_Questionario.Data
{
    public class QuestionarioService
    {
        private static readonly List<Questionario> Questoes;

        static QuestionarioService()
        {
            Questoes = new List<Questionario> {
                new Questionario
                {
                    Pergunta = "Qual o plural de 'batata'?",
                    Opcoes = new List<string> {"Tomatoes", "Potatos", "Potatoes","Potats"},
                    RespostaIndex = 2,
                    Placar = 2
                },
                new Questionario
                {
                    Pergunta = "Qual a resposta da pergunta: Do you like ice-cream?",
                    Opcoes = new List<string> {"Yes, I don't like","No, I Like","Yes, I liked ice-cream","Yes, I do"},
                    RespostaIndex = 3,
                    Placar = 2
                },
                new Questionario
                {
                    Pergunta = "Como se diz 33 em Inglês ?",
                    Opcoes = new List<string> {"Twelve three","Thirty-three","Twenty three","Three three"},
                    RespostaIndex = 1,
                    Placar = 2
                },
                new Questionario
                {
                    Pergunta = "Como se pergunta : 'Posso entrar ?'",
                    Opcoes = new List<string> {"Can I came in?","Can I come in ?","May I came in ?","May I come in ?"},
                    RespostaIndex = 3,
                    Placar = 2
                },
                new Questionario
                {
                    Pergunta = "Qual a tradução para : 'How old you are ?'",
                    Opcoes = new List<string> {"Como você é velho ?","Qual a sua idade ?","Você esta velho ?","Como é ser velho ?"},
                    RespostaIndex = 1,
                    Placar = 2
                }
            };
        }

        public Task<List<Questionario>> GetQuestoesAsync()
        {
            return Task.FromResult(Questoes);
        }
    }
}

A seguir vamos registrar esse serviço na classe Startup, no método ConfigureServices:

       public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddSingleton<QuestionarioService>();
       }

Agora vamos incluir o namespace @using Blazor_Questionario.Data no arquivo _Imports.razor. Assim teremos acesso aos recursos definidos na pasta Data.

Alterando o código do componente Index.razor

O componente Index.razor é onde vamos exibir apenas uma imagem e um texto.

@page "/"
<img src="/images/teste1.jpg" />
<br />
<h4>Verifique o seu nível de conhecimento...</h4>

Criando o componente Questionario.razor

Crie o componente Questionario.razor na pasta Pages e a seguir inclua o código abaixo:

@page "/teste"
@inject QuestionarioService QuestionarioRepositorio
<h1>Teste seu Inglês !</h1>
<p>Seu placar atual é : @placarAtual</p>
@if (questoes == null)
{
    <p><em>Carregando...</em></p>
}
else
{
    int questaoIndex = 0;
    @foreach (var questaoItem in questoes)
    {
        <section>
            <h3>@questaoItem.Pergunta.</h3>
            <div class="form-check">
               @{
                    int opcaoIndex = 0;
                    questaoPlacar.Add(0);
                }
                @foreach (var opcao in questaoItem.Opcoes)
                {
                    int indiceAtualQuestao = questaoIndex;
                    <input class="form-check-input" type="radio" name="@questaoIndex" value="@opcaoIndex" 
                        @onchange="@((eventArgs) => 
                        atualizaPlacar(Convert.ToInt32(eventArgs.Value), indiceAtualQuestao))" />@opcao<br>
                    opcaoIndex++;
                }
            </div>
        </section>
        questaoIndex++;
    }
}
@code {
    List<Blazor_Questionario.Data.Questionario> questoes;
    List<int> questaoPlacar = new List<int>();
    int placarAtual = 0;
    protected override async Task OnInitializedAsync()
    {
        questoes = await QuestionarioRepositorio.GetQuestoesAsync();
    }
    void atualizaPlacar(int indiceRespostaEscolhida, int questaoIndex)
    {
        var questaoItem = questoes[questaoIndex];
        if (indiceRespostaEscolhida == questaoItem.RespostaIndex)
        {
            questaoPlacar[questaoIndex] = questaoItem.Placar;
        }
        else
        {
            questaoPlacar[questaoIndex] = 0;
        }
        placarAtual = questaoPlacar.Sum();
    }
}

Neste código usamos o evento OnInitializedAsync para obter os dados do questionário e a seguir percorremos os dados em um laço foreach onde temos a definição de um input do tipo radio que usa o evento @onchange para atualizar o placar:

  <input class="form-check-input" type="radio" name="@questaoIndex" value="@opcaoIndex"
                        @onchange="@((eventArgs) =>
                        atualizaPlacar(Convert.ToInt32(eventArgs.Value), indiceAtualQuestao))"
/>@opcao<br>

Agora o resultado final ficou assim:

Pegue o código do projeto aqui: Blazor_Questionario.zip  (sem as referências)

"Porque Deus não nos destinou para a ira, mas para a aquisição da salvação, por nosso Senhor Jesus Cristo,
Que morreu por nós, para que, quer vigiemos, quer durmamos, vivamos juntamente com ele."

1 Tessalonicenses 5:9,10
 

     DVDs com programas para estudo e Cursos de VB .NET e C#

       Visite a loja on-line para ver todos os cursos :  Loja do Macoratti.net
 


Referências:


José Carlos Macoratti