Pass values from a form to a method in the Model and return the result to another textbox in the Form

Asked

Viewed 3,063 times

2

I have a very simple form with 3 textbox and a button. I would like to take the value of the first two textbox by clicking the button and passing to a method present in my model and after that return this result to the third textbox. I’m having trouble passing the values and returning using the controller. I’m a beginner in Asp.net mvc if anyone can help. Thanks.

I have this method of Model that I want to use:

public class Conta
{
    [Required]
    public int Num1 { get; set; }
    [Required]
    public int Num2 { get; set; }
    public double Result { get; set; }

    public int Somar(int num1, int num2)
    {
        return num1 + num2;
    }

This in the controller:

 public ActionResult Index()
    {
        return View();
    }

    private static Conta _conta = new Conta();
    [HttpPost]
    public ActionResult Somar(Conta conta)
    {
        _conta.Somar(conta.Num1, conta.Num2);
        return View();
    }

And that’s on the index:

<tr>
    <td>@Html.TextBoxFor(ContaModel => ContaModel.Num1)</td>
</tr>
<tr>
    <td>@Html.TextBoxFor(ContaModel => ContaModel.Num2)</td>
</tr>
<tr>
    <td><input type ="submit" value="Somar" name="Somar"/></td>
</tr>

</table>

As a beginner in this, I don’t know if this is the right way to do it.

  • Hello Paulo Henrique, could post the code you already have?

  • You can edit the question and put the code in it

  • Okay, I was able to put a part of the code in the question.

  • Angularjs (https://angularjs.org/) does not meet this need? https://www.youtube.com/watch?v=RiB0TXOhd3U

2 answers

2

There are some meaningless things in your example. Let’s go to them:

private static Conta _conta = new Conta();

You don’t need to initialize one Model out of a Action of a Controller. There is no use in this, being that the role of a Model is to represent data.

Initially Models are anemic objects (only with properties), but may contain some internal rules, validations and attributes.

This part is ok:

public ActionResult Index()
{
    return View();
}

Already this part, if the goal is to show something on the screen, you must send the object that will be shown to the screen. As well as this does not happen:

[HttpPost]
public ActionResult Somar(Conta conta)
{
    _conta.Somar(conta.Num1, conta.Num2);
    return View();
}

Besides, you’re instantiating a Model to perform two parameters operations of another Model implementing the same class. It makes no sense.

The right thing would be something like this:

conta.Somar(conta.Num1, conta.Num2);

Even better would not need to pass any parameter, after all the properties are of the object itself:

public void Somar()
{
    this.Result = this.Num1 + this.Num2;
}

I mean, the method would look like this:

conta.Somar();

Of course to Result be just a calculated field, something else needs to be noted:

public class Conta
{
    [Required]
    public int Num1 { get; set; }
    [Required]
    public int Num2 { get; set; }
    [NotMapped]
    public double Result { get; set; }

    public void Somar()
    {
        this.Result = this.Num1 + this.Num2;
    }
}

[NotMapped] tells the context that the field should not be mapped into a database, i.e., that the property exists in the class but is not a column of a table or collection of a database.

Back to the return, done the calculation, you need to send the object ready to View. This can be done:

[HttpPost]
public ActionResult Somar(Conta conta)
{
    conta.Somar();
    return View(conta);
}

In this case, we are calling a View calling for Somar.cstml. She needs to be more or less like this:

@model MeuProjeto.Models.Conta

<div>
    Num1: @Model.Num1
</div>
<div>
    Num2: @Model.Num2
</div>
<div>
    Soma: @Model.Result
</div>

If you want to send the result to another View, specify as first argument the name of this View:

[HttpPost]
public ActionResult Somar(Conta conta)
{
    conta.Somar();
    return View("OutraView", conta);
}

In this case, the result will be printed using a View whose file is OutraView.cshtml.

1


Here follows an alternative Gypsy response (which by the way is quite complete):

Here I will be using an AJAX request to perform the sum and return the value.

Model

using System;
using System.ComponentModel.DataAnnotations;

namespace MvcApp
{
    public class Conta
    {
        [Required]
        public int Num1 { get; set; }
        [Required]
        public int Num2 { get; set; }
        public int Result { get; set; }

        public int Somar()
        {
            this.Result = this.Num1 + this.Num2;
            return this.Result;
        }
    }
}

Controller

using System;
using System.Web.Mvc;
using System.Collections.Generic;

namespace MvcApp
{
    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            return View(new Conta());
        }


        [HttpPost]
        public JsonResult Soma(Conta conta)
        {   
            conta.Somar();
            return Json(conta);
        }
    }
}

View

@model MvcApp.Conta
@{
    Layout = null;
}

<!DOCTYPE html>
<!-- template from http://getbootstrap.com/getting-started -->

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script type="text/javascript">
            var virtualPath = "@Url.Content("~/")";
        </script>
    </head>

    <body>
        <div class="container">
            <div>
                @Html.LabelFor(Model => Model.Num1)
                @Html.TextBoxFor(Model => Model.Num1)
            </div>
            <div>
                @Html.LabelFor(Model => Model.Num2)
                @Html.TextBoxFor(Model => Model.Num2)
            </div>
            <div>
                @Html.LabelFor(Model => Model.Result)
                @Html.TextBoxFor(Model => Model.Result, new { @readonly = "readonly", @disabled = "disabled" })
            </div>
            <div>
                <input type ="button" value="Somar" name="Somar"/>
            </div>
        </div>
        <script type="text/javascript">
            var form = {};
            window.onload = function() {
                form.Num1 = document.querySelector("[name='Num1']");
                form.Num2 = document.querySelector("[name='Num2']");
                form.Result = document.querySelector("[name='Result']");
                form.Somar = document.querySelector("[name='Somar']");

                form.Somar.onclick = function (event) {
                    event.stopPropagation();
                    event.preventDefault();
                    somar();
                };
            }

            var urlParameters = function(json) {
                var params = "";
                for (var key in json) {
                    var value = json[key];
                    params += "&" + encodeURIComponent(key) + '=' + encodeURIComponent(value);
                }
                return params.substring(1);
            }

            var somar = function () {
                var conta = {
                    Num1: form.Num1.value,
                    Num2: form.Num2.value,
                    Result: form.Result.value
                };
                var params = urlParameters(conta);

                var xmlHttp = new XMLHttpRequest();
                xmlHttp.open("POST", virtualPath + "Home/Soma", true);
                xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

                xmlHttp.onreadystatechange = function() {
                    if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                        var conta = JSON.parse(xmlHttp.responseText);
                        form.Result.value = conta.Result;
                    }
                }
                xmlHttp.send(params);
            }

        </script>
    </body>
</html>

Dotnetfiddle

Browser other questions tagged

You are not signed in. Login or sign up in order to post.