Add new to-do items
Last updated
Was this helpful?
Last updated
Was this helpful?
O usuário adicionará novas tarefas a fazer com um form (formulário) simples como o abaixo:
Implementar esta funcionalidade requer alguns passos:
Adicionar um form na view
Criar uma nova action no controller para manipular o form
Adicionar código na camada de serviço para atualizar o banco de dados
A view Views/Todo/Index.cshtml
possui um placeholder para o form de inclusão de itens:
Para manter as coisas organizadas e separadas, você criará o form como uma partial view (view parcial). Uma partial view é um pequeno pedaço de uma view maior codificada em um arquivo separado.
Crie a view AddItemPartial.cshtml
:
Views/Todo/AddItemPartial.cshtml
O tag helper asp-action
pode gerar uma URL para o form, assim como quando você o usa em um elemento <a>
. Neste caso, o helper asp-action
é substituído pelo caminho real para a rota AddItem
que você criará:
Adicionar um tag helper asp-
ao elemento <form>
também adiciona um campo oculto ao form que contém um token de verificação. Esse token de verificação pode ser usado para evitar ataques cross-site request forgery (CSRF). Você verificará o token quando escrever o código da action.
Isso cuida da criação da partial view. Agora, faça referência à visualização principal da view Todo:
Views/Todo/Index.cshtml
Quando um usuário clica em Adicionar no form que você acabou de criar, o navegador cria uma solicitação POST para /Todo/AddItem
em seu aplicativo. Isso não funcionará agora, porque não há nenhuma action (ação) que possa manipular a rota /Todo/AddItem
. Se você tentar agora, o ASP.NET Core retornará um erro "404 Not Found" (Não Encontrado).
Você precisará criar uma nova action chamada AddItem
noTodoController
:
Viu como a nova action AddItem
aceita um parâmetro TodoItem
? Este é o mesmo modelo TodoItem
que você criou no capítulo MVC basics para armazenar informações sobre um item de tarefa a fazer. Quando usado aqui como um parâmetro na action, o ASP.NET Core executará automaticamente um processo chamado model binding (binding de modelo).
Model binding examina os dados em uma solicitação e tenta corresponder de maneira inteligente os campos de entrada com propriedades no model. Em outras palavras, quando o usuário envia este form e seus POSTs de navegador para essa action, o ASP.NET Core irá capturar as informações do form e colocá-las na variável newItem
.
O atributo [ValidateAntiForgeryToken]
antes da action diz ao ASP.NET Core que ele deve procurar (e verificar) o token de verificação oculto que foi adicionado ao form pelo tag helper asp-action
. Essa é uma medida de segurança importante para evitar ataques cross-site request forgery (CSRF), em que os usuários podem ser induzidos a enviar dados de um site mal-intencionado. O token de verificação garante que seu aplicativo é realmente aquele que processou e enviou o form.
Dê uma olhada na view AddItemPartial.cshtml
mais uma vez. A linha @model TodoItem
na parte superior do arquivo informa ao ASP.NET Core que a visualização deve estar emparelhada com o modelo TodoItem
. Isto torna possível usar asp-for="Title"
na tag <input>
para que o ASP.NET Core saiba que este elemento de entrada é para a propriedade Title
.
Por causa da linha @ model
, a partial view esperará receber um objetoTodoItem
quando for renderizada. Passar um new TodoItem
através de Html.PartialAsync
inicializa o form com um item vazio. (Tente passar junto { Title = "hello" }
e veja o que acontece!)
Durante o model binding, todas as propriedades de modelo que não podem ser correspondidas com campos no request são ignoradas. Como o form inclui apenas o elemento de entrada Title
, você pode esperar que as outras propriedades em TodoItem
(o flag IsDone
, a data deDueAt
) estarão vazias ou conterão valores default (padrão).
Em vez de reutilizar o model
TodoItem
, outra abordagem seria criar um model separado (comoNewTodoItem
) que é usado apenas para esta action e possui apenas as propriedades específicas (Title) necessárias para adicionar uma novoa tarefa a fazer. Model binding ainda é usado, mas dessa forma você separou o model usado para salvar itens no banco de dados do model usado na requisicao. Às vezes, isso é chamado de binding model ou data transfer object (DTO). Esse padrão de projetos (design pattern) é comum em projetos maiores e mais complexos.
Depois de vincular os dados do request ao model, o ASP.NET Core também realiza validação de modelo (model validation). A validação verifica se os dados ligados ao model do request recebido fazem sentido ou são válidos. Você pode adicionar atributos ao model para informar ao ASP.NET Core como ele deve ser validado.
O atributo [Required]
na propriedade Title
informa ao validador do model do ASP.NET Core para considerar o título inválido se estiver faltando ou em branco. Dê uma olhada no código da action AddItem
: o primeiro bloco verifica se o ModelState
(o resultado da validação do model) é válido. É costume fazer essa verificação de validação logo no início da action:
Se o ModelState
for inválido por qualquer motivo, o navegador será redirecionado para a rota /Todo/Index
, que atualiza a página.
Em seguida, o controller chama o service layer para realizar a operação real do banco de dados de salvar a nova tarefa a fazer:
O método AddItemAsync
retornarátrue
ou false
dependendo se a tarefa foi adicionada com sucesso ao banco de dados. Se falhar por algum motivo, a action retornará um erro HTTP 400 Bad Request
juntamente com um objeto que contenha uma mensagem de erro.
Finalmente, se tudo for concluído sem erros, a action redireciona o navegador para a rota /Todo/Index
, que atualiza a página e exibe a nova lista atualizada de tarefas a fazer para o usuário.
Se você estiver usando um editor de código que entenda C#, você verá o método 'AddItemAsync' sublinhado de vermelho porque o método ainda não existe.
Como último passo, você precisa adicionar um método ao service layer. Primeiro, adicione-o à definição da interface em ITodoItemService
:
Depois, a implementação em TodoItemService
:
A propriedade newItem.Title
já foi definida pelo model binder do ASP.NET Core, portanto, este método só precisa atribuir um ID e definir os valores padrão para as outras propriedades. Em seguida, a nova tarefa é adicionada ao contexto do banco de dados. Na verdade, ela não é salva até que você chame SaveChangesAsync()
. Se a operação for bem sucedida, o método SaveChangesAsync()
retornará 1.
Execute a aplicação e adicione algumas tarefas à sua lista com o formulário. Como as tarefas estão sendo armazenadas no banco de dados, elas ainda estarão lá mesmo depois que a aplicação for parada e iniciada novamente.
Como um desafio extra, tente adicionar um selecionador de data (date picker) usando HTML e JavaScript e deixe o usuário escolher uma data (opcional) para a propriedade "DueAt". Em seguida, use essa data em vez de sempre criar novas tarefas com prazo de 3 dias.