MVC 5 - 页面上的两个独立模型,如何将一个附加到表单以便我可以提交?

时间:2016-02-16 23:59:43

标签: asp.net asp.net-mvc entity-framework asp.net-mvc-5 entity-framework-6

TL; DR:如何处理使用非标准名称提交数据的表单数据?

统计数据:

  • MVC 5
  • ASP.NET 4.5.2

我引入了两种不同的模型:

public async Task<ActionResult> Index() {
  var prospectingId = new Guid(User.GetClaimValue("CWD-Prospect"));
  var cycleId = new Guid(User.GetClaimValue("CWD-Cycle"));
  var viewModel = new OnboardingViewModel();
  viewModel.Prospecting = await db.Prospecting.FindAsync(prospectingId);
  viewModel.Cycle = await db.Cycle.FindAsync(cycleId);
  return View(viewModel);
}

一个名为Prospecting,另一个名为Cycle。 Prospecting的工作正常,因为除了一个小项目之外,页面上的其他内容都不需要它。

循环在页面上有一堆单独的表单,每个表单都需要单独提交,并且只编辑Cycle表的一小部分。我的问题是,我不知道如何将正确的数据提交给后端。我也不完全确定如何“捕获”这些数据。

亮点是显然前端正好反映了数据库中的内容。同样,如果我手动将db字段更改为true值,则复选框最终会在刷新时被选中。

我目前的表格是这样的:

@using(Html.BeginForm("UpdatePDFResourceRequest", "Onboarding", FormMethod.Post, new { enctype = "multipart/form-data" })) {
  @Html.AntiForgeryToken()
  @Html.ValidationSummary(true, "", new { @class = "text-danger" })
  <fieldset>
    @Html.LabelFor(Model => Model.Cycle.PDFResourceLibrary, htmlAttributes: new { @class = "control-label" })
    @Html.CheckBoxFor(Model => Model.Cycle.PDFResourceLibrary, new { @class = "form-control" })
    @Html.ValidationMessageFor(Model => Model.Cycle.PdfResourceLibrary, "", new { @class = "text-danger" })
    <label class="control-label">&nbsp;</label><button type="submit" value="Save" title="Save" class="btn btn-primary glyphicon glyphicon-floppy-disk"></button>
  </fieldset>
}

但结果HTML是这样的:

<input id="Cycle_PDFResourceLibrary" class="form-control" type="checkbox" value="true" name="Cycle.PDFResourceLibrary" data-val-required="'P D F Resource Library' must not be empty." data-val="true">

正如您所看到的,name=Cycle.PDFResourceLibrary,我不知道如何在后端抓住这个。

我对该特定表格的模型是:

public class PDFResourceRequestViewModel {
  [DisplayName("PDF Resource Library Request")]
  public bool PDFResourceLibrary { get; set; }
  [DisplayName("Date Requested")]
  [DataType(DataType.Date)]
  public DateTime PDFResourceLibraryDate { get; set; }
  [DisplayName("Notes")]
  public string PDFResourceLibraryNotes { get; set; }
}

(不是该表的整体模型) 用于处理表单提交的方法是:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> UpdatePDFResourceRequest(PDFResourceRequestViewModel model) {
  var id = new Guid(User.GetClaimValue("CWD-Cycle"));
  Cycle cycle = await db.Cycle.FindAsync(id);
  if(cycle == null) {
    return HttpNotFound();
  }
  try {
    cycle.CycleId = id;
    cycle.PDFResourceLibrary = model.PDFResourceLibrary;
    cycle.PDFResourceLibraryDate = DateTime.Now;
    cycle.PDFResourceLibraryNotes = model.PDFResourceLibraryNotes;
    db.Cycle.Add(cycle);
    await db.SaveChangesAsync();
    return RedirectToAction("Index");
  } catch { }
  return View(model);
}

现在,我知道这个方法是错误的,因为我正在编辑该表中的几十个中的三个值,所以我需要使用this method之类的东西。问题是,表单是使用name= Cycle.PDFResourceLibrary提交的,并且后端没有匹配。

帮助?

1 个答案:

答案 0 :(得分:1)

您可以使用[Bind(Prefix="Cycle")]属性来排除&#39;剥离&#39;前缀使name="Cycle.PDFResourceLibrary"有效变为name="PDFResourceLibrary"并绑定到PDFResourceRequestViewModel

public async Task<ActionResult> UpdatePDFResourceRequest([Bind(Prefix="Cycle")]PDFResourceRequestViewModel model)