简体   繁体   中英

ASP.NET Core MVC drop down list will not repopulate

I have this drop-down list in my project, and when I use the HttpPost method I have to repopulate it or it's going to throw a null error. I did that, and it worked like normal. However, I'm trying to change a record on my database, and in order to do that, I need the Id to be in the URL. I changed my code in the _Layout to allow the user Id to be automatically entered when they click the tab. But when that happens it throws "ArgumentNullException: Value cannot be null. (Parameter 'items')." Even though I repopulated it. If I don't add the Id, it works, but I change the record on the database. What's going on, why is it not repopulating like before? Also, this is pertaining to the Payee method in the Account controller.

_Layout:

@using Microsoft.AspNetCore.Identity
@using The_Bank_of_Cardinal.Areas.Identity.Data

@inject SignInManager<CardinalUser> SignInManager
@inject UserManager<CardinalUser> UserManager

<style>
    #menu ul li {
        /*float: left;
        border: 1px;
        border-style: solid;*/
    }
    #menu ul li a:hover{
        background-color: lightgray;
    }
    #menu ul ul {
        display: none;
        height: auto;
        padding: 0px;
        margin: 0px;
        border: 1px;
        position: absolute;
        border-style: solid;
        background-color: white;
        z-index : 5000;
    }
    #menu ul li:hover > ul{

        display: block;
    }
</style>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - The Bank of Cardinal</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                @if (SignInManager.IsSignedIn(User))
                    {
                        <a class="navbar-brand" asp-area="" asp-controller="Account" asp-action="Index">The Bank of Cardinal</a>
                    }else
                        { 
                            <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">The Bank of Cardinal</a>
                        }
        
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div id="menu" class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <partial name="_LoginPartial.cshtml" />
                    <ul class="navbar-nav flex-grow-1">
                        @if (SignInManager.IsSignedIn(User))
                        {
                            <li class="nav-item"><a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Index">User Account</a></li>
                            <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Transactions">Transaction History</a></li>
                            <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Deposit" asp-route-id="@UserManager.GetUserAsync(User).Result.Id">Deposit</a></li>
                            <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Transfers">Transfers</a>
                                                  <ul>
                                                      <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Payee" asp-route-id="@UserManager.GetUserAsync(User).Result.Id">User Pay</a>
                                                      
                                                      <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="BillPay" asp-route-id="@UserManager.GetUserAsync(User).Result.Id">Bill Pay </a>
                                                      
                                                      <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="AddPayee">Create Payee</a>
                                                  </ul>
                            </li>
                        }
                        else
                        {

                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Transactions">Transactions</a>
                            </li>
                            @*<li class="nav-item">
                <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Test">Test</a>
            </li>*@
                            @*<li class="nav-item">
                <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Data">User Data</a>
            </li>*@
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Info">User Info</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                            </li>
                        }

                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2021 - The_Bank_of_Cardinal - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @RenderSection("Scripts", required: false)
</body>
</html>

Account controller:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using The_Bank_of_Cardinal.Areas.Identity.Data;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using The_Bank_of_Cardinal.Models;






namespace The_Bank_of_Cardinal.Controllers
{
   
       
   
    
    [Authorize]
    public class AccountController : Controller
    {
        private readonly TransactionConnection _tc;
        private readonly UserManager<CardinalUser> userManager;
        private readonly SignInManager<CardinalUser> signInManager;
        private readonly DepositConnection _dc;
        private readonly PayeeConnection _pc;
        public AccountController(TransactionConnection tc, UserManager<CardinalUser> userManager, SignInManager<CardinalUser> signInManager, DepositConnection dc, PayeeConnection pc)
        {
            _tc = tc;
            this.userManager = userManager;
            this.signInManager = signInManager;
            _dc = dc;
            _pc = pc;
        }
        public IActionResult Index()
        {
            return View();
        }
        public IActionResult Transactions()
        {
            var results = _tc.TransactionHistory.Where(o=> o.UserName == userManager.GetUserAsync(User).Result.UserName).ToList();
            return View(results);
        }

        public IActionResult Test() 
        {
            return View();
        }
        [HttpGet]
        public IActionResult Deposit(string Id)
        {
            var resultss = _dc.AspNetUsers.Where(s => s.Id == Id).FirstOrDefault();
            
            return View(resultss);
        }
        [HttpPost]
        public IActionResult Deposit(DepositModel model, TransactionModel tm)
        {
            
            var resultss = _dc.AspNetUsers.Where(s => s.Id == model.Id).FirstOrDefault();
            double test = model.AccountBalance + userManager.GetUserAsync(User).Result.AccountBalance;


            tm.UserName = userManager.GetUserAsync(User).Result.UserName;
            string name = tm.UserName;
            tm.Description = "personal deposit";
            tm.TransactionType = "Deposit";
            tm.Amount = "$" + model.AccountBalance.ToString();
            tm.Date = DateTime.Now;

            model.AccountBalance = test;

            _tc.TransactionHistory.Add(tm);
            _tc.SaveChanges();


            _dc.AspNetUsers.Remove(resultss);
            _dc.AspNetUsers.Add(model);
            _dc.SaveChanges();


            //_dc.AspNetUsers.


            return Content("This is your info \n" + 
                $"Name: {name} \n" + 
                $"Description: {tm.Description} \n" + 
                $"type: {tm.TransactionType} \n" + 
                $"Amount {tm.Amount} \n");
        }
        public IActionResult Transfers()
        {
            return View();
        }
        [HttpGet]
        public IActionResult AddPayee() {


            return View();
        
        }
        [HttpPost]
        public IActionResult AddPayee(PayeeModel pm)
        {
            if (ModelState.IsValid)
            {
                pm.UserName = userManager.GetUserAsync(User).Result.UserName;
                _pc.Payee.Add(pm);
                _pc.SaveChanges();

                return RedirectToAction("Transfers");
            }

            return View();
        }
        [HttpGet]
        public IActionResult Payee(string Id)
        {

            var resultss = _dc.AspNetUsers.Where(s => s.Id == Id).FirstOrDefault();
            
            List<PayeeModel> li = new List<PayeeModel>();
            
            li = _pc.Payee.Where(s => s.UserName == userManager.GetUserAsync(User).Result.UserName).ToList();
            
            ViewBag.payeeNames = li;


            return View();
        }
        [HttpPost]
        public IActionResult Payee(PayPayee pp, TransactionModel tm, DepositModel model)
        {
            if (ModelState.IsValid)
            {
                

                var resultss = _dc.AspNetUsers.Where(s => s.Id == model.Id).FirstOrDefault();
                tm.Description = "You Transfered money to the user named " + pp.Name;
                tm.Amount = pp.Amount.ToString();
                tm.TransactionType = "User Pay";
                tm.Date = DateTime.Now;
                tm.UserName = userManager.GetUserAsync(User).Result.UserName;
                model.AccountBalance = userManager.GetUserAsync(User).Result.AccountBalance - pp.Amount;

                

                _tc.TransactionHistory.Add(tm);
                _tc.SaveChanges();
                _dc.AspNetUsers.Remove(resultss);
                _dc.AspNetUsers.Add(model);
                _dc.SaveChanges();


                List<PayeeModel> li = new List<PayeeModel>();
                li = _pc.Payee.Where(s => s.UserName == userManager.GetUserAsync(User).Result.UserName).ToList();
                ViewBag.payeeNames = li;


                return View("Transfers");
                
            }
            else
            {
                return View();
            }


        }

        [HttpGet]
        public IActionResult BillPay(string Id)
        {
            var resultss = _dc.AspNetUsers.Where(s => s.Id == Id).FirstOrDefault();
            return View();
        }
        [HttpPost]
        public IActionResult BillPay(BillPayModel bp, TransactionModel tm, DepositModel model)
        {
           
                var resultss = _dc.AspNetUsers.Where(s => s.Id == model.Id).FirstOrDefault();
                tm.Amount = "$" + bp.Amount.ToString();
                tm.UserName = userManager.GetUserAsync(User).Result.UserName;
                tm.Description = "you sent " + bp.Company + " a payment \n with the account number " + bp.AccountNumber;
                tm.TransactionType = "Bill pay";
                tm.Date = DateTime.Now;
                model.AccountBalance = userManager.GetUserAsync(User).Result.AccountBalance - bp.Amount;

                _tc.TransactionHistory.Add(tm);
                _tc.SaveChanges();
                _dc.AspNetUsers.Remove(resultss);
                _dc.AspNetUsers.Add(model);
                _dc.SaveChanges();

                return RedirectToAction("Transfers");
            
        }
    }
}

PayPayee model:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace The_Bank_of_Cardinal.Models
{
    public class PayPayee
    {
        public string Name { get; set; }
        public double Amount { get; set; }
    }
}

Payee view:

@model The_Bank_of_Cardinal.Models.PayPayee

@{
    ViewData["Title"] = "Payee";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Payee</h1>

<h4>PayeeModel</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Payee">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <select asp-for="Name" asp-items="@(new SelectList(@ViewBag.payeeNames, "Payee", "Payee"))"></select>
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label  asp-for="Amount" class="control-label"></label>
                <input  asp-for="Amount" class="form-control" />
                <span asp-validation-for="Amount" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

You only need to set ViewBag outside if (ModelState.IsValid) :

[HttpPost]
        public IActionResult Payee(PayPayee pp, TransactionModel tm, DepositModel model)
        {
            List<PayeeModel> li = new List<PayeeModel>();
                li = _pc.Payee.Where(s => s.UserName == userManager.GetUserAsync(User).Result.UserName).ToList();
                ViewBag.payeeNames = li;
            if (ModelState.IsValid)
            {
                

                var resultss = _dc.AspNetUsers.Where(s => s.Id == model.Id).FirstOrDefault();
                tm.Description = "You Transfered money to the user named " + pp.Name;
                tm.Amount = pp.Amount.ToString();
                tm.TransactionType = "User Pay";
                tm.Date = DateTime.Now;
                tm.UserName = userManager.GetUserAsync(User).Result.UserName;
                model.AccountBalance = userManager.GetUserAsync(User).Result.AccountBalance - pp.Amount;

                

                _tc.TransactionHistory.Add(tm);
                _tc.SaveChanges();
                _dc.AspNetUsers.Remove(resultss);
                _dc.AspNetUsers.Add(model);
                _dc.SaveChanges();


                


                return View("Transfers");
                
            }
            else
            {
                return View();
            }


        }

Without if (ModelState.IsValid) ,sometimes it will get error when you add data to database.

If your IActionResult with [HttpGet] has a Id as Parameter and you return View or return RedirectToAction then you need to pass the value, to the returned View

Example:

[HttpGet]
public IActionResult Test(string id)
{
   //Some code here
   return View();
}
[HttpPost]
public IActionResult Test(Bind["Id,FirstName,LastName"] Person model)
{
   //some code here
   return RedirectToAction(nameof(Test), (new {model.Id}));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM