ASP.NET-MVC-网站运行总功能不起作用



试图创建一个跑步总数,作为大学作业的一部分,为我的网站计算卡路里。一切都结束了,除了这一部分,它一直让我绊倒。理论上,它应该取一个值,并将其添加到一个正在运行的总数中,然后显示这个总数,但我认为每次按下按钮计算这个值时,它都会运行我用来计算这个值的模型的一个新实例。操作有3个文件相互作用

  1. 卡路里计数.cs-包含数据和计算的模型

    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
    namespace BlairMackenzie_CalorieCount.Models
    {
    public class CalorieCount
    {
    // Stores user input for calculating calorie count
    [Required]
    [Display(Name = "Calories Consumed")]
    public int CalorieIntake { get; set; }
    // Stores the running total
    [Display(Name = "Total Calories Consumed Today")]
    public int TotalCalorieCount { get; set; }
    // This method calculates total calorie count
    public void CalculateTotalCalorieCount()
    {
    // Add CalorieIntake to TotalCalorieCount
    TotalCalorieCount += CalorieIntake;
    }
    }
    }
    
  2. 卡路里计数器cshtml-向用户显示所有这些并获取输入的网页


@{
ViewBag.Title = "CalorieCounter";
}
<h2>Calorie Counter</h2>
<br />
<hr />
@using (Html.BeginForm())
{
<div class="table-responsive">
<table class="table table-lg">
<tr>
<!-- Displays label and input box for CalorieIntake -->
<td>@Html.LabelFor(m => m.CalorieIntake)</td>
<td>@Html.EditorFor(m => m.CalorieIntake)</td>
</tr>
<tr>
<!-- Displays label and display for TotalCalorieCount -->
<td>@Html.LabelFor(m => m.TotalCalorieCount)</td>
<td>@Html.DisplayFor(m => m.TotalCalorieCount)</td>
</tr>
<tr>
<td></td>
<td>
<!-- Submit button triggers calculation -->
<input type="submit" value="Calculate New Total Calories" class="btn btn-lg btn-success" />
</td>
</tr>
</table>
</div>
}
  1. HomeController.cs-处理加载页面和调用模型以处理计算
// Loads Calorie Count Page
// Sets up empty form
[HttpGet]
public ActionResult CalorieCounter()
{
return View();
}
// This action is called when the user clicks the submit button
// The completed form is sent to the back end
[HttpPost]
public ActionResult CalorieCounter(CalorieCount model)
{
if (ModelState.IsValid)
{
model.CalculateTotalCalorieCount();
}
return View(model); // Return the model to the view with all values calculated
}

如果有人能发现这个问题并提出解决方案,那将非常感谢。

这里存在一些根本性的误解。ASP。NET MVC本质上是一个";"无国籍";系统因此,当您从浏览器向服务器发出请求时,服务器上的所有都是全新的、未初始化的内存。它是"newing up";用于处理请求和发送响应的所有对象。

因此,如果您有一点数据想要在请求之间保持不变,那么您有两个选项:

  1. 确保您需要的所有数据都是";"往返跳闸";每次。这通常意味着你需要在页面中隐藏<input />字段来包含表单中的数据。只要这些输入设置正确(我建议使用HtmlHelper,即Html.HiddenFor<T>()(,框架就会匹配值,并在POST处理程序中设置模型对象的属性
  2. 将数据存储在服务器上的数据库中。每个请求加载当前数据,向其中添加新的数量,并保存它,然后在页面上显示它需要的任何内容

更新

在根据您的示例创建了一个可工作的MVC站点并复制了该问题之后,我做了一些研究,发现HtmlHelpers在查看传递给视图的模型之前先查看ModelState。这就是该值从不更新的原因。我还注意到有一个验证错误,因为int TotalCalorieCount暗示需要一个值,可能0还不够好。

以下是我为使其发挥作用所做的:

  1. 在视图中的提交按钮之前立即添加@Html.HiddenFor(m => m.TotalCalorieCount)
  2. CalorieCount.TotalCalorieCount设为int?,而不是int(这删除了要存在的DataAnnotations隐含要求(
  3. HomeController中的if (ModelState.IsValid)块内立即添加了对ModelState.Clear()的调用

它现在像你对我的期望一样工作。

HomeController.cs

// Loads Calorie Count Page
// Sets up empty form
[HttpGet]
public ActionResult CalorieCounter()
{
return View();
}
// This action is called when the user clicks the submit button
// The completed form is sent to the back end
[HttpPost]
public ActionResult CalorieCounter(CalorieCount model)
{
if (ModelState.IsValid)
{
ModelState.Clear();
model.CalculateTotalCalorieCount();
}
return View(model); // Return the model to the view with all values calculated
}

卡路里计数.cs

using System.ComponentModel.DataAnnotations;
namespace WebApplication1.Models
{
public class CalorieCount
{
// Stores user input for calculating calorie count
[Required]
[Display(Name = "Calories Consumed")]
public int CalorieIntake { get; set; }
// Stores the running total
[Display(Name = "Total Calories Consumed Today")]
public int? TotalCalorieCount { get; set; }
// This method calculates total calorie count
public void CalculateTotalCalorieCount()
{
// Add CalorieIntake to TotalCalorieCount
TotalCalorieCount = (TotalCalorieCount ?? 0) + CalorieIntake;
}
}
}

卡路里计数器cshtml

@model CalorieCount
@{
ViewBag.Title = "CalorieCounter";
}
<h2>Calorie Counter</h2>
<br />
<hr />
@using (Html.BeginForm())
{
<div class="table-responsive">
<table class="table table-lg">
<tr>
<!-- Displays label and input box for CalorieIntake -->
<td>@Html.LabelFor(m => m.CalorieIntake)</td>
<td>@Html.EditorFor(m => m.CalorieIntake)</td>
</tr>
<tr>
<!-- Displays label and display for TotalCalorieCount -->
<td>@Html.LabelFor(m => m.TotalCalorieCount)</td>
<td>@Html.DisplayFor(m => m.TotalCalorieCount)</td>
</tr>
<tr>
<td></td>
<td>
<!-- Submit button triggers calculation -->
@Html.HiddenFor(m => m.TotalCalorieCount)
<input type="submit" value="Calculate New Total Calories" class="btn btn-lg btn-success"/>
</td>
</tr>
</table>
</div>
}

最后一件事。如果你不想让CalorieCount.TotalCalorieCount成为一个可以为null的int,你可以在GET中向你的视图返回一个模型,就像这样:

// Loads Calorie Count Page
// Sets up empty form
[HttpGet]
public ActionResult CalorieCounter()
{
return View(new CalorieCount() { TotalCalorieCount = 0 });
}

这也解决了这部分问题。

最终通过为CalorieCount模型创建DbSet来解决此问题,并将每次计算都存储在该数据库中。控制器将循环浏览该数据库,直到找到显示其为最新计算的最大id,并将TotalCalorieCount存储在本地变量中,添加CalorieIntake并将本地变量发送到模型,以便在网页上显示。

最新更新