每次单击按钮时都会生成 Razor 页面列表
Razor Pages List get's generated at every button click
我有一个 Recipe 对象,它有一个成分列表,我创建了一个 AddRecipe 页面,其中有一个成分列表,我希望它在创建时由用户填充。
问题是,我可以将东西添加到列表中,在调试器中我可以看到列表的长度增加了,我可以看到列表中的新成分,但是如果我添加一个新的成分,它似乎它取代了列表,或覆盖了它,所以我不能像这样在该列表中存储超过 1 个东西
这里是 AddRecipe.cshtml 代码:
<div class="row">
<div class="col">
<div class="form-group">
<table class="table table-striped border">
<tr class="table-secondary">
<th>
Name
</th>
<th>
Quantity
</th>
<th>
Price
</th>
<th>
Calories
</th>
</tr>
@foreach (var item in Model.Ingredients)
{
<tr>
<td>
@Html.DisplayFor(m => item.Name)
</td>
<td>
@Html.DisplayFor(m => item.Quantity)
</td>
<td>
@Html.DisplayFor(m => item.Price)
</td>
<td>
@Html.DisplayFor(m => item.Calories)
</td>
</tr>
}
</table>
</div>
</div>
<div class="col">
<div class="form-group">
<form method="post">
<div class="m-1"> Ingredient: <input type="text" name="ingredientName" /> </div>
<div class="m-1"> Amount: <input type="number" name="ingredientAmount" /> </div>
<div class="m-1"> Price: <input type="number" name="ingredientPrice" /> </div>
<div class="m-1"> Calories: <input type="number" name="ingredientCalories" /> </div>
<button asp-page-handler="AddNew">Add!</button>
</form>
</div>
</div>
</div>
这是 .cshtml.cs 文件:
public class AddRecipeModel : PageModel
{
private readonly IApiClient _apiClient;
public AddRecipeModel(IApiClient apiClient)
{
_apiClient = apiClient;
}
[BindProperty]
public Recipe Recipe { get; set; }
public List<Ingredient> Ingredients { get; set; } = new List<Ingredient>();
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
return RedirectToPage("./Index");
}
public void OnPostAddNew(string ingredientName, int ingredientAmount, int ingredientPrice, int ingredientCalories)
{
Ingredient newIngredient = new Ingredient(ingredientName, ingredientPrice, ingredientAmount, ingredientCalories);
Ingredients.Add(newIngredient);
}
}
你可以尝试在form中添加name="Ingredients[x].xxx"
的hidden input(.net core bind data with name属性),并在Ingredients前添加[BindProperty]
,这样当form post ,隐藏输入的数据将绑定到 Ingredients.Here 是一个演示:
型号:
public class Ingredient
{
public string Name { get; set; }
public int Quantity { get; set; }
public int Price { get; set; }
public int Calories { get; set; }
public Ingredient(){
}
public Ingredient(string name,int quantity,int price,int calories)
{
Name = name;
Quantity = quantity;
Price = price;
Calories = calories;
}
}
cshtml:
<div class="row">
<div class="col">
<div class="form-group">
<table class="table table-striped border">
<tr class="table-secondary">
<th>
Name
</th>
<th>
Quantity
</th>
<th>
Price
</th>
<th>
Calories
</th>
</tr>
@foreach (var item in Model.Ingredients)
{
<tr>
<td>
@Html.DisplayFor(m => item.Name)
</td>
<td>
@Html.DisplayFor(m => item.Quantity)
</td>
<td>
@Html.DisplayFor(m => item.Price)
</td>
<td>
@Html.DisplayFor(m => item.Calories)
</td>
</tr>
}
</table>
</div>
</div>
<div class="col">
<div class="form-group">
<form method="post">
<div class="m-1"> Ingredient: <input type="text" name="ingredientName" /> </div>
<div class="m-1"> Amount: <input type="number" name="ingredientAmount" /> </div>
<div class="m-1"> Price: <input type="number" name="ingredientPrice" /> </div>
<div class="m-1"> Calories: <input type="number" name="ingredientCalories" /> </div>
@{var i = 0; }
@foreach (var item in Model.Ingredients)
{
<input hidden asp-for="@item.Name" name="Ingredients[@i].Name" />
<input hidden asp-for="@item.Quantity" name="Ingredients[@i].Quantity" />
<input hidden asp-for="@item.Price" name="Ingredients[@i].Price" />
<input hidden asp-for="@item.Calories" name="Ingredients[@i].Calories" />
i++;
}
<button asp-page-handler="AddNew">Add!</button>
</form>
</div>
</div>
</div>
cshtml.cs:
public class AddRecipeModel : PageModel
{
private readonly IApiClient _apiClient;
public AddRecipeModel(IApiClient apiClient)
{
_apiClient = apiClient;
}
[BindProperty]
public Recipe Recipe { get; set; }
[BindProperty]
public List<Ingredient> Ingredients { get; set; } = new List<Ingredient>();
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
return RedirectToPage("./Index");
}
public void OnPostAddNew(string ingredientName, int ingredientAmount, int ingredientPrice, int ingredientCalories)
{
Ingredient newIngredient = new Ingredient(ingredientName, ingredientPrice, ingredientAmount, ingredientCalories);
Ingredients.Add(newIngredient);
}
}
结果:
我有一个 Recipe 对象,它有一个成分列表,我创建了一个 AddRecipe 页面,其中有一个成分列表,我希望它在创建时由用户填充。
问题是,我可以将东西添加到列表中,在调试器中我可以看到列表的长度增加了,我可以看到列表中的新成分,但是如果我添加一个新的成分,它似乎它取代了列表,或覆盖了它,所以我不能像这样在该列表中存储超过 1 个东西
这里是 AddRecipe.cshtml 代码:
<div class="row">
<div class="col">
<div class="form-group">
<table class="table table-striped border">
<tr class="table-secondary">
<th>
Name
</th>
<th>
Quantity
</th>
<th>
Price
</th>
<th>
Calories
</th>
</tr>
@foreach (var item in Model.Ingredients)
{
<tr>
<td>
@Html.DisplayFor(m => item.Name)
</td>
<td>
@Html.DisplayFor(m => item.Quantity)
</td>
<td>
@Html.DisplayFor(m => item.Price)
</td>
<td>
@Html.DisplayFor(m => item.Calories)
</td>
</tr>
}
</table>
</div>
</div>
<div class="col">
<div class="form-group">
<form method="post">
<div class="m-1"> Ingredient: <input type="text" name="ingredientName" /> </div>
<div class="m-1"> Amount: <input type="number" name="ingredientAmount" /> </div>
<div class="m-1"> Price: <input type="number" name="ingredientPrice" /> </div>
<div class="m-1"> Calories: <input type="number" name="ingredientCalories" /> </div>
<button asp-page-handler="AddNew">Add!</button>
</form>
</div>
</div>
</div>
这是 .cshtml.cs 文件:
public class AddRecipeModel : PageModel
{
private readonly IApiClient _apiClient;
public AddRecipeModel(IApiClient apiClient)
{
_apiClient = apiClient;
}
[BindProperty]
public Recipe Recipe { get; set; }
public List<Ingredient> Ingredients { get; set; } = new List<Ingredient>();
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
return RedirectToPage("./Index");
}
public void OnPostAddNew(string ingredientName, int ingredientAmount, int ingredientPrice, int ingredientCalories)
{
Ingredient newIngredient = new Ingredient(ingredientName, ingredientPrice, ingredientAmount, ingredientCalories);
Ingredients.Add(newIngredient);
}
}
你可以尝试在form中添加name="Ingredients[x].xxx"
的hidden input(.net core bind data with name属性),并在Ingredients前添加[BindProperty]
,这样当form post ,隐藏输入的数据将绑定到 Ingredients.Here 是一个演示:
型号:
public class Ingredient
{
public string Name { get; set; }
public int Quantity { get; set; }
public int Price { get; set; }
public int Calories { get; set; }
public Ingredient(){
}
public Ingredient(string name,int quantity,int price,int calories)
{
Name = name;
Quantity = quantity;
Price = price;
Calories = calories;
}
}
cshtml:
<div class="row">
<div class="col">
<div class="form-group">
<table class="table table-striped border">
<tr class="table-secondary">
<th>
Name
</th>
<th>
Quantity
</th>
<th>
Price
</th>
<th>
Calories
</th>
</tr>
@foreach (var item in Model.Ingredients)
{
<tr>
<td>
@Html.DisplayFor(m => item.Name)
</td>
<td>
@Html.DisplayFor(m => item.Quantity)
</td>
<td>
@Html.DisplayFor(m => item.Price)
</td>
<td>
@Html.DisplayFor(m => item.Calories)
</td>
</tr>
}
</table>
</div>
</div>
<div class="col">
<div class="form-group">
<form method="post">
<div class="m-1"> Ingredient: <input type="text" name="ingredientName" /> </div>
<div class="m-1"> Amount: <input type="number" name="ingredientAmount" /> </div>
<div class="m-1"> Price: <input type="number" name="ingredientPrice" /> </div>
<div class="m-1"> Calories: <input type="number" name="ingredientCalories" /> </div>
@{var i = 0; }
@foreach (var item in Model.Ingredients)
{
<input hidden asp-for="@item.Name" name="Ingredients[@i].Name" />
<input hidden asp-for="@item.Quantity" name="Ingredients[@i].Quantity" />
<input hidden asp-for="@item.Price" name="Ingredients[@i].Price" />
<input hidden asp-for="@item.Calories" name="Ingredients[@i].Calories" />
i++;
}
<button asp-page-handler="AddNew">Add!</button>
</form>
</div>
</div>
</div>
cshtml.cs:
public class AddRecipeModel : PageModel
{
private readonly IApiClient _apiClient;
public AddRecipeModel(IApiClient apiClient)
{
_apiClient = apiClient;
}
[BindProperty]
public Recipe Recipe { get; set; }
[BindProperty]
public List<Ingredient> Ingredients { get; set; } = new List<Ingredient>();
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
return RedirectToPage("./Index");
}
public void OnPostAddNew(string ingredientName, int ingredientAmount, int ingredientPrice, int ingredientCalories)
{
Ingredient newIngredient = new Ingredient(ingredientName, ingredientPrice, ingredientAmount, ingredientCalories);
Ingredients.Add(newIngredient);
}
}
结果: