带有多个可选复选框的 Visual Studio Code 中的 Html 表单:
<form name="CarServ" id="myForm">
<div>
<label>CarModel:</label>
<input type="text" id="model" size="65" name="CarModel" placeholder="Enter Car Model" required>
</div>
<div class="check">
<label>Addons:</label>
<input type="checkbox" name ="SelectedCheckboxes[]" value="10%off First service visit" id="10%off First service visit">
<label for="10%off First service visit">10%off First service visit</label>
<input type="checkbox" name="SelectedCheckboxes[]" value="10%off Waterwash" id="10%off Waterwash">
<label for="10%off Waterwash">10%off Waterwash</label>
<input type="checkbox" name ="SelectedCheckboxes[]" value="Free AC Inspection" id="Free AC Inspection">
<label for="Free AC Inspection">Free AC Inspection</label>
</div>
<button id="btn" type="submit">Submit</button>
</form>
dotnet core api 中的三种模型, CarForm.cs:
public class CarForm
{
public int Id { get; set; }
[Required]
public string CarModel { get; set; }
[Required]
public string SelectedCheckboxes { get; set; }
public IList<Selection> Selections { get; set; }
}
插件.cs:
public class Addon
{
public int Id { get; set; }
public string CheckboxName { get; set; }
public IList<Selection> Selections { get; set; }
}
Selection.cs:
public class Selection
{
public int CarFormId { get; set; }
public CarForm CarForms { get; set; }
public Addon Addons { get; set; }
public int AddonId { get; set; }
}
CarDbContext.cs:
public class CarDbContext : DbContext
{
public CarDbContext(DbContextOptions<CarDbContext> options) : base(options)
{
}
public DbSet<CarForm> CarForms { get; set; }
public DbSet<Addon> Addons { get; set; }
public DbSet<Selection> Selections { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Selection>()
.HasKey(s => new { s.CarFormId, s.AddonId });
modelBuilder.Entity<Addon>().HasData(
new Addon { Id = 1, CheckboxName = "10%off First service visit" },
new Addon { Id = 2, CheckboxName = "10%off Waterwash" },
new Addon { Id = 3, CheckboxName = "Free AC Inspection" });
}
}
创建控制器类:
namespace CarServiceFormApi.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class CarServiceFormController : ControllerBase
{
private readonly CarDbContext _context;
public CarServiceFormController(CarDbContext context)
{
_context = context;
}
[HttpPost("submit-form")]
public IActionResult SubmitForm([FromBody] CarForm carForm)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Save the CarForm to the database
_context.CarForms.Add(carForm);
_context.SaveChanges();
// Create the selections for the CarForm
var selections = carForm.SelectedCheckboxes.Select(id => new Selection
{
CarFormId = carForm.Id,
AddonId = id
});
_context.Selections.AddRange(selections);
_context.SaveChanges();
return Ok();
}
[HttpGet("get-form-data/{id}")]
public async Task<IActionResult> GetFormData(int id)
{
// Retrieve the CarForm from the database
var carForm = await _context.CarForms.Include(cf => cf.Selections).ThenInclude(s => s.Addons).FirstOrDefaultAsync(cf => cf.Id == id);
if (carForm == null)
{
return NotFound();
}
// Return the CarForm as JSON
return Ok(carForm);
}
}
}
基本上我想要实现的是,我的 html 表单输入详细信息必须发布到 API 并存储在数据库中。然后,使用 GET 方法,我试图在成功时将数据检索回控制台。由于它是一个多选复选框,我将一组 Selectedcheckboxes 传递给 API 并尝试将其存储在数据库中。
现在当我运行我的 html 表单时,我在控制台上收到一个错误,如
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-d0f3aa9cab0ad5f1450f6bbb403a1a9c-adf3f2910efaeafb-00","errors":{"CarModel":["The CarModel field is required."],"Selections":["The Selections field is required."],"SelectedCheckboxes":["The SelectedCheckboxes field is required."]}}
它显示“选择”字段是必需的!但我还没有在“CarForm.cs”中声明一个选择字段。我希望我的“CarForm.cs”上的选择线是执行链接模型的功能。无法弄清楚我在代码中哪里出错了。
尝试将
SelectedCheckboxes[]
更改为简单的SelectedCheckboxes
。当后端实际上是单个字符串值时,您正试图绑定一个列表。 Selections
字段与 CarForm
具有循环依赖性。最好创建一个与 DTO 数据库关系不紧密耦合的单独视图模型。
基本上我想要实现的是,我的 html 表单输入详细信息 必须发布到 API 并存储在数据库中。然后,使用 GET 方法我试图在成功时将数据检索回控制台
根据您的描述和场景,您的代码片段确实看起来合乎逻辑,即使我不认为它的气味仍然存在,您也在使简单的东西变得嘈杂和笨拙。
为了实现 API 和 HTML 的东西,javascript 可能是理想的选择,但是,它可以在没有它的情况下实现,甚至可以在一般的 MVC 控制器上实现。
除此之外,我认为您的模型设计也是不必要的,因为我们只需要一个插件列表和汽车详细信息,除了不清楚您为什么使用该关系设计之外。
让我们开始行动,我们如何以更简洁的方式完成您的场景:
使用 MVC 控制器:
型号:
如前所述,我需要的只是汽车 mdoel 和插件。因此,我将所有这些修改为 CarFormViewModel。
public class Addon
{
public int Id { get; set; }
public string? CheckboxName { get; set; }
public bool IsChecked { get; set; }
}
public class CarFormViewModel
{
public int Id { get; set; }
public string? CarModel { get; set; }
public List<Addon>? Addons { get; set; }
}
控制器:
public IActionResult LoadView()
{
var addonsList = new List<Addon>()
{
new Addon() { Id=1,CheckboxName="10% off First service visit", IsChecked = false },
new Addon() { Id=2,CheckboxName="10% off Waterwash", IsChecked = false },
new Addon() { Id=3,CheckboxName="Free AC Inspection", IsChecked = false },
};
var model = new CarFormViewModel();
model.Addons = addonsList;
return View(model);
}
景色:
@model DotNetCoreTestApp.Models.CarFormViewModel
@{
ViewData["Title"] = "Car Addons Check Box List";
}
<form asp-action="SubmitCarAddonSelectedValue" asp-controller="Home" method="post">
<table class="table table-striped table-bordered mr-3 ml-3">
<tr>
<th> <label asp-for="CarModel"></label></th>
<td> <input asp-for="CarModel" class="form-control" placeholder="Enter Car Model" /><span asp-validation-for="CarModel"></span></td>
</tr>
<tr>
<th>Addons:</th>
<th>
@for (int i = 0; i < Model.Addons?.Count; i++)
{
<label>@Model.Addons[i].CheckboxName</label>
<input asp-for="@Model.Addons[i].IsChecked" />
<input type="hidden" asp-for="@Model.Addons[i].Id" />
<input type="hidden" asp-for="@Model.Addons[i].CheckboxName" />
}
</th>
</tr>
</table>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
提交后操作:
[HttpPost]
public IActionResult SubmitCarAddonSelectedValue(CarFormViewModel carFormViewModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var selectedAddonsValueFromView = carFormViewModel.Addons?.Where(selectedAddons => selectedAddons.IsChecked == true).ToList();
//Insert your addons in database
return Ok(selectedAddonsValueFromView);
}
输出:
使用 API 控制器:
景色:
在视图中只需要改变这种格式的 API 路由 URL [email protected]("SubmitForm","CarServiceForm") 如下:
@model DotNetCoreTestApp.Data.CarFormViewModel
@{
ViewData["Title"] = "Combatant Check Box List";
}
<form id="SubmitForm" method="post" [email protected]("SubmitForm","CarServiceForm")>
<table class="table table-striped table-bordered mr-3 ml-3">
<tr>
<th> <label asp-for="CarModel"></label></th>
<td> <input asp-for="CarModel" class="form-control" placeholder="Enter Car Model" /><span asp-validation-for="CarModel"></span></td>
</tr>
<tr>
<th>Addons:</th>
<th>
@for (int i = 0; i < Model.Addons?.Count; i++)
{
<label>@Model.Addons[i].CheckboxName</label>
<input asp-for="@Model.Addons[i].IsChecked" />
<input type="hidden" asp-for="@Model.Addons[i].Id" />
<input type="hidden" asp-for="@Model.Addons[i].CheckboxName" />
}
</th>
</tr>
</table>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
API控制器:
[HttpPost("SubmitForm")]
public IActionResult SubmitForm([FromForm] CarFormViewModel carFormViewModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
//Get Car Details
var carDetails = carFormViewModel.CarModel;
//Get Addons Details
var selectedAddonsValueFromView = carFormViewModel.Addons?.Where(selectedAddons => selectedAddons.IsChecked == true).ToList();
//Do whatever you want to do in database
return Ok(carFormViewModel);
}
输出:
注意:如果您想知道如何实现使用javascript您可以在这里查看我们的官方文档