ASP.NET Core MVC table 一直显示相同的数字
ASP.NET Core MVC table keeps showing same number
我完全不知所措。一切似乎都是正确的。当我查看数据库时,提交的数字是正确的。但是当我去列出数据库中的数据时,数据库列表中的Amount
列总是相同的数字。
当您转到存款选项卡时,您输入的第一个数字始终是将要显示的数字。因此,如果我输入 50 美元,50 美元将出现在交易选项卡中。但是,假设我回去投入 60 美元。它在交易历史选项卡中仍显示 50 美元,但在数据库中显示 60 美元。为什么不显示数据库中的号码?
账户管理员:
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;
public AccountController(TransactionConnection tc, UserManager<CardinalUser> userManager, SignInManager<CardinalUser> signInManager, DepositConnection dc)
{
_tc = tc;
this.userManager = userManager;
this.signInManager = signInManager;
_dc = dc;
}
public IActionResult Index()
{
return View();
}
public IActionResult Transactions()
{
var results = _tc.TransactionHistory.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();
int 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();
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();
}
}
}
交易视图:
@model IEnumerable<The_Bank_of_Cardinal.Models.TransactionModel>
@{
ViewData["Title"] = "Transactions";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Transactions</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
@*<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.UserName)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th>
@Html.DisplayNameFor(model => model.TransactionType)
</th>
<th>
@Html.DisplayNameFor(model => model.Amount)
</th>
<th>
@Html.DisplayNameFor(model => model.Date)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.DisplayFor(modelItem => item.TransactionType)
</td>
<td>
@Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
@Html.DisplayFor(modelItem => item.Date)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
</table>*@
<div class="container">
@if (Model != null)
{
<table class="table table-dark">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Description</th>
<th scope="col">Transaction Type</th>
<th scope="col">Amount</th>
<th scope="col">Date</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => item.UserName)</td>
<td>@Html.DisplayFor(modelItem => item.Description)</td>
<td>@Html.DisplayFor(modelItem => item.TransactionType)</td>
<td>@Html.DisplayFor(modelItem => item.Amount)</td>
<td>@Html.DisplayFor(modelItem => item.Date)</td>
</tr>
}
</tbody>
</table>
}
</div>
存款视图:
@model The_Bank_of_Cardinal.Models.DepositModel
@{
ViewData["Title"] = "Deposit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Deposit</h1>
<h4>DepositModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Deposit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label hidden asp-for="Id" class="control-label"></label>
<input hidden asp-for="Id" class="form-control" />
<span asp-validation-for="Id" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="AccountBalance" class="control-label">Amount</label>
<input asp-for="AccountBalance" class="form-control" value="0" />
<span asp-validation-for="AccountBalance" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Deposit" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
存款模型:
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using The_Bank_of_Cardinal.Areas.Identity.Data;
namespace The_Bank_of_Cardinal.Models
{
public class DepositModel
{
[Key]
public string Id { get; set; }
public int AccountBalance { get; set; }
}
}
交易模式:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace The_Bank_of_Cardinal.Models
{
public class TransactionModel
{
[Key]
public string UserName { get; set; }
public string Description { get; set; }
public string TransactionType { get; set; }
public string Amount { get; set; }
public DateTime Date { get; set; }
}
}
存款DbContext
:
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace The_Bank_of_Cardinal.Models
{
public class DepositConnection : DbContext
{
public DepositConnection(DbContextOptions<DepositConnection> options) : base(options)
{
}
public DbSet<DepositModel> AspNetUsers { get; set; }
}
}
交易DbContext
:
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace The_Bank_of_Cardinal.Models
{
public class TransactionConnection : DbContext
{
public TransactionConnection(DbContextOptions<TransactionConnection> options) : base(options)
{
}
public DbSet<TransactionModel> TransactionHistory { get; set; }
}
}
- 您使用
@Html.XXXFor()
不正确。
- 当你想使用 HTML-helpers 用于 HTML
<form>
来自 ViewModel 中集合的输入绑定时,你需要使用 for()
,而不是 foreach()
并且您需要 For()
表达式中的 [int index]
索引器。
- 当你需要绑定一个表单对象/表单模型时和传递额外的数据在您看来,对单向数据使用
ViewData
,对双向数据使用 Model
。
- 我认为 ASP.NET MVC 和 ASP.NET Core 的视图模型和表单绑定系统需要重新思考,因为它完全错误要求 ViewModel 对象也是绑定的 表单模型 。在我自己的项目中,我对 ASP.NET 核心有自己的扩展,以允许我干净地使用单独的 types/objects。
- 虽然我无法修复您的
ActionLink
项
<tbody>
@for( int i = 0; i < this.Model.Count; i++ ) {
<tr>
<td>
@Html.DisplayFor( m => m[i].UserName )
</td>
<td>
@Html.DisplayFor( m => m[i].Description )
</td>
<td>
@Html.DisplayFor( m => m[i].TransactionType )
</td>
<td>
@Html.DisplayFor( m => m[i].Amount )
</td>
<td>
@Html.DisplayFor( m => m[i].Date )
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
class TransactionModel
有主键 属性 UserName
。
但是您有多个具有相同 UserName
值的 TransactionModel
实例。这是矛盾的。每个 TransactionModel
主键必须是唯一的。
将您的 TransactionModel
class 更改为:
public class TransactionModel
{
public int Id { get; set; } // This is the primary key.
public string UserName { get; set; }
public string Description { get; set; }
public string TransactionType { get; set; }
public decimal Amount { get; set; }
public DateTime Date { get; set; }
}
属性 Id
是您的主键。它将自动递增。这是约定俗成的。参见:https://docs.microsoft.com/en-us/ef/core/modeling/keys?tabs=data-annotations#configuring-a-primary-key
旁注:属性 Amount
的类型应该是十进制而不是字符串,因此在上面的示例中对此进行了更改。本着同样的精神,枚举可能是 TransactionType
属性.
的更好选择
您当然需要使用 class TransactionModel
修改代码以考虑其新定义。
我完全不知所措。一切似乎都是正确的。当我查看数据库时,提交的数字是正确的。但是当我去列出数据库中的数据时,数据库列表中的Amount
列总是相同的数字。
当您转到存款选项卡时,您输入的第一个数字始终是将要显示的数字。因此,如果我输入 50 美元,50 美元将出现在交易选项卡中。但是,假设我回去投入 60 美元。它在交易历史选项卡中仍显示 50 美元,但在数据库中显示 60 美元。为什么不显示数据库中的号码?
账户管理员:
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;
public AccountController(TransactionConnection tc, UserManager<CardinalUser> userManager, SignInManager<CardinalUser> signInManager, DepositConnection dc)
{
_tc = tc;
this.userManager = userManager;
this.signInManager = signInManager;
_dc = dc;
}
public IActionResult Index()
{
return View();
}
public IActionResult Transactions()
{
var results = _tc.TransactionHistory.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();
int 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();
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();
}
}
}
交易视图:
@model IEnumerable<The_Bank_of_Cardinal.Models.TransactionModel>
@{
ViewData["Title"] = "Transactions";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Transactions</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
@*<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.UserName)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th>
@Html.DisplayNameFor(model => model.TransactionType)
</th>
<th>
@Html.DisplayNameFor(model => model.Amount)
</th>
<th>
@Html.DisplayNameFor(model => model.Date)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.DisplayFor(modelItem => item.TransactionType)
</td>
<td>
@Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
@Html.DisplayFor(modelItem => item.Date)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
</table>*@
<div class="container">
@if (Model != null)
{
<table class="table table-dark">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Description</th>
<th scope="col">Transaction Type</th>
<th scope="col">Amount</th>
<th scope="col">Date</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => item.UserName)</td>
<td>@Html.DisplayFor(modelItem => item.Description)</td>
<td>@Html.DisplayFor(modelItem => item.TransactionType)</td>
<td>@Html.DisplayFor(modelItem => item.Amount)</td>
<td>@Html.DisplayFor(modelItem => item.Date)</td>
</tr>
}
</tbody>
</table>
}
</div>
存款视图:
@model The_Bank_of_Cardinal.Models.DepositModel
@{
ViewData["Title"] = "Deposit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Deposit</h1>
<h4>DepositModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Deposit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label hidden asp-for="Id" class="control-label"></label>
<input hidden asp-for="Id" class="form-control" />
<span asp-validation-for="Id" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="AccountBalance" class="control-label">Amount</label>
<input asp-for="AccountBalance" class="form-control" value="0" />
<span asp-validation-for="AccountBalance" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Deposit" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
存款模型:
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using The_Bank_of_Cardinal.Areas.Identity.Data;
namespace The_Bank_of_Cardinal.Models
{
public class DepositModel
{
[Key]
public string Id { get; set; }
public int AccountBalance { get; set; }
}
}
交易模式:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace The_Bank_of_Cardinal.Models
{
public class TransactionModel
{
[Key]
public string UserName { get; set; }
public string Description { get; set; }
public string TransactionType { get; set; }
public string Amount { get; set; }
public DateTime Date { get; set; }
}
}
存款DbContext
:
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace The_Bank_of_Cardinal.Models
{
public class DepositConnection : DbContext
{
public DepositConnection(DbContextOptions<DepositConnection> options) : base(options)
{
}
public DbSet<DepositModel> AspNetUsers { get; set; }
}
}
交易DbContext
:
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace The_Bank_of_Cardinal.Models
{
public class TransactionConnection : DbContext
{
public TransactionConnection(DbContextOptions<TransactionConnection> options) : base(options)
{
}
public DbSet<TransactionModel> TransactionHistory { get; set; }
}
}
- 您使用
@Html.XXXFor()
不正确。 - 当你想使用 HTML-helpers 用于 HTML
<form>
来自 ViewModel 中集合的输入绑定时,你需要使用for()
,而不是foreach()
并且您需要For()
表达式中的[int index]
索引器。 - 当你需要绑定一个表单对象/表单模型时和传递额外的数据在您看来,对单向数据使用
ViewData
,对双向数据使用Model
。- 我认为 ASP.NET MVC 和 ASP.NET Core 的视图模型和表单绑定系统需要重新思考,因为它完全错误要求 ViewModel 对象也是绑定的 表单模型 。在我自己的项目中,我对 ASP.NET 核心有自己的扩展,以允许我干净地使用单独的 types/objects。
- 虽然我无法修复您的
ActionLink
项
<tbody>
@for( int i = 0; i < this.Model.Count; i++ ) {
<tr>
<td>
@Html.DisplayFor( m => m[i].UserName )
</td>
<td>
@Html.DisplayFor( m => m[i].Description )
</td>
<td>
@Html.DisplayFor( m => m[i].TransactionType )
</td>
<td>
@Html.DisplayFor( m => m[i].Amount )
</td>
<td>
@Html.DisplayFor( m => m[i].Date )
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
class TransactionModel
有主键 属性 UserName
。
但是您有多个具有相同 UserName
值的 TransactionModel
实例。这是矛盾的。每个 TransactionModel
主键必须是唯一的。
将您的 TransactionModel
class 更改为:
public class TransactionModel
{
public int Id { get; set; } // This is the primary key.
public string UserName { get; set; }
public string Description { get; set; }
public string TransactionType { get; set; }
public decimal Amount { get; set; }
public DateTime Date { get; set; }
}
属性 Id
是您的主键。它将自动递增。这是约定俗成的。参见:https://docs.microsoft.com/en-us/ef/core/modeling/keys?tabs=data-annotations#configuring-a-primary-key
旁注:属性 Amount
的类型应该是十进制而不是字符串,因此在上面的示例中对此进行了更改。本着同样的精神,枚举可能是 TransactionType
属性.
您当然需要使用 class TransactionModel
修改代码以考虑其新定义。