Obtendo dados da View no Controller com ASP.NET MVC

Introdução

Esse artigo explica como acessar dados de uma view no método de ação do controller. Um método de ação (Action method) é um método comum em C# que pode ou não aceitar parâmetros no controller.

Nós usaremos 2 tipos de métodos HTTP para tratar a solicitação do nosso navegador;  um é o HTTP GET e o outro é o HTTP POST. Quando chamamos um método de ação através de uma URL no navegador o método HTTP GET é chamado, e quando fazemos uma solicitação através de um evento de click de botão o método HTTP POST é chamado. Portanto neste artigo vou explicar como acessar os dados do campo input da view no método de ação do controller quando uma solicitação HTTP POST é chamada.

Exemplo de Solicitação GET e POST

Para compreendermos como acessar dados do input que está na view no método de ação (POST) do controller criei uma aplicação “Calcular Juros Simples”. Essa aplicação recebe Capital, Taxa e o Tempo como entrada do usuário e gera o juros simples. Vamos proceder com a aplicação.

Crie um método de ação no controller CalcularJurosSimples (CalcularJurosSimplesController.cs) que renderiza view na interface do usuário.

public class CalcularJurosSimplesController : Controller
{
    // GET: CalcularJurosSimples
    public ActionResult Index()
    {
        return View();
    }
}

Crie uma view para o usuário entrar com os dados, o código é o seguinte:

Calcular Juros Simples

Entradas de dados para calcular juros simples
Figura 1. Entradas de dados para calcular

obtendo os dados da view no método de ação

Agora vou explicar os 4 jeitos de recuperar os dados da view no controller. Eles são:

  • Usar a abordagem tradicional
  • Usar o objeto FormCollection
  • Usar parâmetros
  • Model fortemente tipada ligada a view

usar a abordagem tradicional

Na abordagem tradicional nós usamos o objeto da solicitação (request) da classe HttpRequestBase. O objeto da solicitação possuí os valores dos campos input em pares nome/valor. Quando criamos um botão de submit o tipo de request POST é criado e chama o método POST.

Figura 2. Dados do request
Figura 2. Dados do request

Nós temos três dados, na estrutura de par nome/valor. Então podemos acessar esses dados no método POST passando o nome do campo como um índice do objeto Request e obter seu valor. O método que trata o POST é exibido a seguir:

[HttpPost]
public ActionResult ResultadoCalcularJurosSimples()
{
    decimal principal = Convert.ToDecimal(Request["txtCapital"].ToString());
    decimal taxa = Convert.ToDecimal(Request["txtTaxaJuros"].ToString());
    int tempo = Convert.ToInt32(Request["txtAno"].ToString());

    decimal jurosSimples = (principal * tempo * taxa) / 100;

    StringBuilder sbJuros = new StringBuilder();
    sbJuros.Append("<b>Capital :</b> " + principal + "<br/>");
    sbJuros.Append("<b>Taxa :</b> " + taxa + "<br/>");
    sbJuros.Append("<b>Tempo(ano) :</b> " + tempo + "<br/>");
    sbJuros.Append("<b>Juros Simples :</b> " + jurosSimples);
    return Content(sbJuros.ToString());
}

Quando executado, obtemos o resultado apresentado abaixo:

Figura 3. Tela de saída
Figura 3. Tela de saída

usar o objeto FormCollection 

Nós também podemos obter dados da solicitação (request) através do objeto FormCollection. O objeto FormCollection também possuí os dados em uma estrutura de nome/valor como o objeto Request. Para obter dados através do objeto FormCollection nós precisamos passar ele como parâmetro e ele possuíra todos os campos input enviados no formulário.

[HttpPost]
public ActionResult ResultadoCalcularJurosSimples(FormCollection formulario)
{
    decimal principal = Convert.ToDecimal(formulario["txtCapital"].ToString());
    decimal taxa = Convert.ToDecimal(formulario["txtTaxaJuros"].ToString());
    int tempo = Convert.ToInt32(formulario["txtAno"].ToString());

    decimal jurosSimples = (principal * tempo * taxa) / 100;

    StringBuilder sbJuros = new StringBuilder();
    sbJuros.Append("<b>Capital :</b> " + principal + "<br/>");
    sbJuros.Append("<b>Taxa :</b> " + taxa + "<br/>");
    sbJuros.Append("<b>Tempo(ano) :</b> " + tempo + "<br/>");
    sbJuros.Append("<b>Juros Simples :</b> " + jurosSimples);
    return Content(sbJuros.ToString());
}

Esse código também retorna o mesmo que a figura 3 mostra.

Usar parâmetros

Nós também podemos passar os nomes dos campos inputs como um parâmetro do método de ação do tipo post. O atributo nome do campo input e o nome do parâmetro devem ser o mesmo. Esses parâmetros recebem o valor digitado pelo usuário no input. Então podemos acessar os valores dos inputs da view através de parâmetros. Um campo do tipo input aceita uma string no html, portanto o parâmetro deve possuir o tipo string. Não há a necessidade de definir os parâmetros em nenhuma ordem.

[HttpPost]
public ActionResult ResultadoCalcularJurosSimples(string txtCapital, string txtTaxaJuros, string txtAno)
{
    decimal principal = Convert.ToDecimal(txtCapital);
    decimal taxa = Convert.ToDecimal(txtTaxaJuros);
    int tempo = Convert.ToInt32(txtAno);

    decimal jurosSimples = (principal * tempo * taxa) / 100;

    StringBuilder sbJuros = new StringBuilder();
    sbJuros.Append("<b>Capital :</b> " + principal + "<br/>");
    sbJuros.Append("<b>Taxa :</b> " + taxa + "<br/>");
    sbJuros.Append("<b>Tempo(ano) :</b> " + tempo + "<br/>");
    sbJuros.Append("<b>Juros Simples :</b> " + jurosSimples);
    return Content(sbJuros.ToString());
}

Esse código também retorna o mesmo que a figura 3 mostra.

Em todas as 3 abordagens nós estamos convertendo um tipo string para tipos numéricos. Se alguma das conversões falhar, toda a ação irá falhar. Poderiamos tratar as exceções, mas isso também aumentaria a quantidade de código. A quarta abordagem pode reduzir a quantidade de código e ficar muito mais elegante.

Model fortemente tipada ligada a view

Nós relacionamos uma model a view; isso é conhecido como tipagem forte.

Passo 1: Crie uma classe model para Juros Simples.

namespace CalcularJurosSimples.Models
{
    public class JurosSimples
    {
        public decimal Capital { get; set; }
        public decimal TaxaJuros { get; set; }
        public int Ano { get; set; }
    }
}

Passo 2: Criar um método de ação que renderiza a view.

Nós estamos passando uma instância vazia para a view.

public ActionResult FortementeTipada()
{
    var model = new JurosSimples();
    return View(model);
}

Passo 3: Criar uma view fortemente tipada semelhante a Figura 1.

@model CalcularJurosSimples.Models.JurosSimples

@{
    ViewBag.Title = "Juros Simples";
}
@using (Ajax.BeginForm("ResultadoCalcularJurosSimples", "CalcularJurosSimples",
                            new AjaxOptions { UpdateTargetId = "divResultado" }))
{

    <fieldset>
        <legend>Calcular juros simples</legend>
        <div id="divResultado"></div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Capital)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Capital)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.TaxaJuros)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.TaxaJuros)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Ano)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Ano)
        </div>
        <p>
            <input type="submit" value="Calcular" />
        </p>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Passo 4: Criar um método post que recebe como parâmetro a classe modelo criada. Nesta implementação não precisamos converter tipos ou escrever código extra.

[HttpPost]
public ActionResult ResultadoCalcularJurosSimples(JurosSimples model)
{
      decimal jurosSimples = (model.Capital* model.Ano* model.TaxaJuros) / 100;

      StringBuilder sbJuros = new StringBuilder();
      sbJuros.Append("<b>Capital :</b> " + model.Capital + "<br/>");
      sbJuros.Append("<b>Taxa :</b> " + model.TaxaJuros+ "<br/>");
      sbJuros.Append("<b>Tempo(ano) :</b> " + model.Ano + "<br/>");
      sbJuros.Append("<b>Juros Simples :</b> " + jurosSimples);
      return Content(sbJuros.ToString());
}

Esse código também retorna o mesmo que a figura 3 mostra.

Via Getting Data From View to Controller in MVC por Sandeep Shekhawat

Published by Vitor Reis

Full stack software engineer at Delivery Hero focused in systems for logistics

Join the Conversation

3 Comments

    1. Olá Felipe,

      A minha abordagem preferida é usar a view fortemente tipada, para este exemplo o código da view está disponível na seção: Passo 3: Criar uma view fortemente tipada semelhante a Figura 1.

      Abraço

      Like

  1. Oi vitor, interessante seu post, mas acredito eu que falta mais explicação do código, você apenas o mostrou.
    é o caso do passo 3 na view tipada.

    Like

Leave a comment

Leave a reply to Felipe Laera Cancel reply