I am getting this error message with the following code "RuntimeBinderException: Cannot perform runtime binding on a null reference" and can't solve

Viewed 13

This is the Model that I have:

namespace MattsSportsEmporium.Models
{
    public class PriceCalculator
    {
        public decimal Subtotal { get; set; }
        public decimal TaxPercent { get; set; }
        public decimal TaxAmount { get; set; }
        public decimal Total { get; set; }
        public decimal CalculatePrice()
        {

            decimal Total = (Subtotal * (TaxAmount / 100)) + Subtotal;

            return Total;
        }

        public decimal CalculateTax()
        {

            decimal TaxAmount = Subtotal * (TaxPercent / 100);

            return TaxAmount;
        }

    }
}

This is the Controller:

using Microsoft.AspNetCore.Mvc;
using MattsSportsEmporium.Models;


namespace MattsSportsEmporium.Controllers
{
    public class HomeController : Controller
    {
        [HttpGet]
        public IActionResult Index(decimal Total)
        {

            ViewBag.CP = 0;
            return View();
        }
        [HttpPost]
        public IActionResult Index(PriceCalculator model)
        {
            ViewBag.CP = model.CalculatePrice();
            return View(model);
        }

        [HttpGet]
        public IActionResult Index1(decimal TaxAmount)
        {

            ViewBag.CT = 0;
            return View();
        }
        [HttpPost]
        public IActionResult Index1(PriceCalculator model)
        {
            ViewBag.CT = model.CalculateTax();
            return View(model);
        }
    }
}

This is the View:

@using MattsSportsEmporium.Models
@model PriceCalculator
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Matt's Sports Emporium</title>
    <style>
        /* all of the CSS styles from figure 2-14 go here */
        body {
            padding: 1em;
            font-family: Arial, Arial, Helvetica, sans-serif;
        }

        h1 {
            margin-top: 0;
            color: navy;
        }

        label {
            display: inline-block;
            width: 10em;
            padding-right: 1em;
        }

        div {
            margin-bottom: .5em;
        }
    </style>
</head>
<body>
    <h1>Matt's Sports Emporium</h1>
    <form asp-action="Index" method="post">
        <div>
            <label asp-for="Subtotal">
                Subtotal:
            </label>
            <input asp-for="Subtotal" />
        </div>
        <div>
            <label asp-for="TaxPercent">
                Tax Percent:
            </label>
            <input asp-for="TaxPercent" />
        </div>
        <div>
            <label>TaxAmount: </label>
            <input value="@ViewBag.CT.ToString("C2")" readonly />

        </div>
        <div>
            <label>Total: </label>
            <input value="@ViewBag.CP.ToString("C2")" readonly />
        </div>
        <button type="submit">Calculate</button>
        <a asp-action="Index">Clear</a>
    </form>
</body>
</html>

The app should display an input box where the user enters a subtotal followed by an input box where the user enters a tax percentage. The next line displays the tax based on the first two user entries. The last line displays the total with tax.

1 Answers

The idea of achieving the above function is incorrect base on your solution.

This for your model is sufficient

 public class PriceCalculator
    {
        public decimal Subtotal { get; set; }
        public decimal TaxPercent { get; set; }
        public decimal TaxAmount { get; set; }
        public decimal Total { get; set; }

        public void CalculateTotal()
        {
            decimal _TaxAmount = Math.Round(SubTotal * TaxPercent / 100,2);
            decimal _Total = SubTotal + _TaxAmount;
            
            TaxAmount = _TaxAmount;
            Total = _Total;

        }
    }

On your controller. That is sufficient

 public IActionResult Index()
        {
            PriceCalculator model = new PriceCalculator();

            model.TaxPercent = 6; // pass your tax value here

            return View(model);
        }
      
       [HttpPost]
       public IActionResult Index(decimal SubTotal, decimal TaxPercent)
        {
           ModelState.Clear();

            PriceCalculator model = new PriceCalculator();

           model.SubTotal = SubTotal;
           model.TaxPercent = TaxPercent;

           model.CalculateTotal(); //calcualte here

            return View(model); // then return back the model
        }

In your view

<body>
    <h1>Matt's Sports Emporium</h1>
    <form asp-action="Index" method="post">
        <div>
            <label asp-for="Subtotal">
                Subtotal:
            </label>
            <input asp-for="Subtotal" onChange= "CalculateTotal()" />
        </div>
        <div>
            <label asp-for="TaxPercent">
                Tax Percent:
            </label>
            <input asp-for="TaxPercent"/>
        </div>
        <div>
            <label>TaxAmount: </label>
            <input asp-for="TaxAmount" ReadOnly = True"/>

        </div>
        <div>
            <label asp-for="Total">
               Total:
            </label>
            <input asp-for="Total"/>
        </div>
        <button type="submit">Calculate</button>
        <a asp-action="Index">Clear</a>
    </form>
</body>

This is one of the way to achieve what u try to do. However, this solution is rather weak. You should use javascript in the view to do the calculation instead of post back to calculate the total.

Related