-1

I have gone through lot of posts however unable to resolve this issue.

  1. I input some values on the View and click the Submit button
  2. My repo calculates the payment schedule based on the criteria and displays the list (that's what I am trying to achieve)

This is where I am having issues. On the initial load my Model is null and I get the null reference exception.

I have just started coding with asp so please ignore the basics in this case. Any suggestions would be helpful

@model FinanceApplication.ViewModels.LoanViewModel
    @using (Html.BeginForm("Index", "Home", FormMethod.Post))
    {
        <div>
            <table style="width: 35%;" class="style1">
                <tr>
                    <td>Enter Price</td>
                    <td>@Html.TextBoxFor(model => model.Amount)</td>
                </tr>
                <tr>
                    <td>Enter Deposit</td>
                    <td>@Html.TextBoxFor(model => model.Deposit)</td>
                </tr>
                <tr>
                    <td>Finance Option</td>

                    <td>
                        @Html.DropDownListFor(model => 
                            model.Term, new SelectList(Enum.GetValues(typeof(Options))),
                          "Select Option", 
                          new { @class = "form-control" })
                    </td>
                </tr>
                <tr>
                    <td>Delivery Date</td>
                    <td>
                        @Html.EditorFor(model => model.Deliverydate)
                    </td>
                </tr>
                <tr>
                    <td>Arrangement Fee</td>
                    <td>@Html.TextBoxFor(model => model.ArrangementFee)</td>
                </tr>
                <tr>
                    <td>Completion Fee</td>
                    <td>@Html.TextBoxFor(model => model.CompletionFee)</td>
                </tr>
                <tr>
                    <td>
                        <input type="submit" id="btnSubmit" 
                               value="Submit" onclick="myFunction();" />
                    </td>
                </tr>
            </table>
        </div>



        <div id="loan-form" class="text-left">
        <h1>Payment Schedule</h1>
        <table>
            <tr>
                <td>Amount (£) </td>
                <td>@Html.DisplayFor(model => model.Amount)</td>
            </tr>
            <tr>
                <td>Loan Amount (£) </td>
                <td>@Html.DisplayFor(model => model.LoanAmount)</td>
            </tr>
            <tr>
                <td>Deposit (£) </td>
                <td>@Html.DisplayFor(model => model.Deposit)</td>
            </tr>
            <tr>
                <td>Term (years) </td>
                <td>@Html.DisplayFor(model => model.Term)</td>
            </tr>
            <tr>
                <td>Delivery Date</td>
                <td>@Html.DisplayFor(model => model.Deliverydate)</td>
            </tr>
            <tr>
                <td>
                    <table class="table table-striped">
                        <thead>
                            <tr>
                                <th>Payment Date</th>
                                <th>Payment Amount (£) </th>
                                <th>Total Paid (£) </th>
                                <th>Balance (£) </th>
                            </tr>
                        </thead>
                        <tbody>
                            if(Model != null)
                            { 
                                @foreach (var item in Model.PaymentSchedule)
                                {
                                <tr>
                                    <td> @Html.DisplayFor(modelItem => 
                                                  item.PaymentDate) </td>
                                    <td> @Html.DisplayFor(modelItem =>  
                                                  item.PaymentAmount) </td>
                                    <td> @Html.DisplayFor(modelItem =>  
                                                  item.TotalPaid) </td>
                                    <td> @Html.DisplayFor(modelItem =>  
                                                  item.RemainingBalance) </td>

                                </tr>
                                }
                            }
                            else
                            {
                            <tr>
                                <td>No Items found</td>
                            </tr>

                            }
                        </tbody>
                    </table>
                </td>
            </tr>
        </table>

        </div>
    }


 {  
     private IPaymentScheduleRepository _paymentScheduleRepository;

     public HomeController(IPaymentScheduleRepository paymentScheduleRepository)
     {  
     _paymentScheduleRepository = paymentScheduleRepository; }

     [HttpGet]
     public IActionResult Index()
     { return View(new LoanViewModel()); }

     [HttpPost]
     public async Task<IActionResult> Index(LoanViewModel requestParameters)
     { LoanViewModel output = await _paymentScheduleRepository.GetPaymentSchedule(requestParameters);
         return View("Index", output);}}
//ViewModel
public class LoanViewModel
{
    [Required(ErrorMessage = "Please enter the loan amount.")]
    [Range(1, 100000000, 
      ErrorMessage = "Loan amount must be between 1,000 and 1000,000.")]
    public decimal Amount { get; set; }

    [Required(ErrorMessage = "Please enter the deposit amount.")]
    [Remote(action: "VerifyDeposit", controller:"Home")]
    public decimal Deposit { get; set; }

    [Required(ErrorMessage = "Please select the term of the loan.")]
    public string Term { get; set; }

    [Required(ErrorMessage = "Please select the delivery date.")]
    [DataType(DataType.Date)]
    [Display(Name = "Delivery Date")]
    [DisplayFormat(ApplyFormatInEditMode = true, 
      DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime Deliverydate { get; set; }

    public decimal ArrangementFee { get; set; }

    public decimal CompletionFee { get; set; }

    public decimal LoanAmount
    {
        get { return (Amount - Deposit); }
    }

    [Display(Name = "Payment Schedule")]
    public List<SheduledPayments> PaymentSchedule { get; set; }        
}

//PaymentSchedule
public class SheduledPayments 
{
    public DateTime PaymentDate { get; set; }
    public decimal PaymentAmount { get; set; }
    public decimal RemainingBalance { get; set; }
    public decimal TotalPaid { get; set; }
}
Rals
  • 1
  • 1
  • Are you getting to the Async method? One possibility is the Async method is return before the Model is fully created and giving an error. – jdweng Sep 12 '19 at 10:35
  • Just goes to [HttpGet] public ActionResult Index() { return View(); } and then to the view - which I know doesn't have model in it... – Rals Sep 12 '19 at 10:42
  • So request parameters are null? – jdweng Sep 12 '19 at 10:47
  • Yes as its initially loading and that's where its failing – Rals Sep 12 '19 at 10:51
  • I would put a break point and use Call Stack to find out why there are not request parameters. The calling method should of set the parameters. – jdweng Sep 12 '19 at 10:56
  • `@foreach (var item in Model.PaymentSchedule)` won't work if `return View(new LoanViewModel());` runs. This is because `Model.PaymentSchedule` is still `null`. You should change `public List PaymentSchedule { get; set; }` to `public List PaymentSchedule { get; set; } = new List();` – mjwills Sep 12 '19 at 12:10
  • Please show the source code for `GetPaymentSchedule`. – mjwills Sep 12 '19 at 12:16
  • [HttpGet] public IActionResult Index() { return View(new LoanViewModel()); } - updated the paymentschedule as you suggested however has to return a new LoanViewModel when getting the Index() on initial load - which I didnt wanted as it prefills the textbox with 0 values – Rals Sep 12 '19 at 14:48

2 Answers2

1

On the initial load your view model returns null - hint.

You should have a method for loading the view i.e get and a method for posting the view i.e. post.

Depending on context you need to work with the model in both action methods.

Check this and post the action method on your initial load.

  • Thanks for this - initially its a get - Index() and that's where the Model is null but how come I don't have this issue with model – Rals Sep 12 '19 at 14:50
  • upload all of your controller code please. it will make it easier to help. –  Sep 12 '19 at 15:08
  • Added the entire Controller code. Thanks – Rals Sep 12 '19 at 15:27
  • you need to initialize the parameters in your model. If there is a property that expects a value on your get method and it is passed into your view, it will return null. When you click post i expect this would be the same behavior as it goes back to the get method after you post. Can you put up the entire exception message? –  Sep 12 '19 at 15:40
  • upvote my answer if you like it please. –  Sep 13 '19 at 09:46
0

For the decimal values you can use the ?? operator, for the date you can use the ternary operator ?:

. . .
<td>@Html.DisplayFor((modelItem => (item.PaymentDate == null ? new DateTime(1900,1,1):item.PaymentDate)))</td> 
<td>@Html.DisplayFor(modelItem => item.PaymentAmount ?? 0)</td>
. . . 

see this for more informations.

Otherway If the problem is the first call, your model is not defined so you must initialize the parameters in the model constructor.

Davide Castronovo
  • 1,366
  • 8
  • 21
  • thanks for this - have updated accordingly however it fails when the Index() returns the View which does not have the actual model. – Rals Sep 12 '19 at 10:43