我正在使用MVC 4,ASP.NET。我有一个问题是将复选框值传递给控制器中的post方法。它返回null值。
这是我的观点的一部分(获取工作并正确填充数据):
@using (Html.BeginForm())
{
<fieldset>
<table>
<tr>
@{
int cnt = 0;
List<LearningEnterprises.ViewModel.AssignedVendor> techs = ViewBag.Tech;
foreach (var tech in techs)
{
if (cnt++ % 3 == 0)
{
@:</tr><tr>
}
@:<td>
<input type="checkbox"
name="selectedTechs"
value="@tech.TechID"
@(Html.Raw(tech.Assigned ? "checked=\"checked\"" : "")) />
@tech.TechID @: @tech.Title
@:</td>
}
@:</tr>
}
</table>
<p>
<input type="submit" value="Save" id="save" />
</p>
</fieldset>
}
这是我的帖子:
[Authorize(Roles = "Admin")]
[HttpPost, ValidateInput(false)]
public ActionResult EditVendor(int? id, string[] selectedTech)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var vendor = db.Vendors
.Include(i => i.VendorType)
.Include(i=>i.Stocks)
.Where(i => i.ID == id)
.Single();
if (TryUpdateModel(vendor, "",
new string[] { "CompanyName", "PhoneNumber", "Address", "ProvinceState", "City", "Country", "PostalCode", "Email", "numberofBooths", "comments", "electric", "internet", "tonicEquipment", "VendorTypeID" }))
{
try
{
UpdateVendorTech(selectedTech, vendor);
db.Entry(vendor).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
PopulateAssignedTechData(vendor);
PopulateDropDownLists(vendor.VendorTypeID);
return View(vendor);
}
string [] selectedTech在debug中显示空值。它应该等于视图中选中的复选框的id值。
答案 0 :(得分:0)
我能看到的第一件事就是你的名字不匹配:你的控制器中有string[] selectedTech
但视图中有name = "selectedTechs"
,那么ASP.NET绑定器无法找到任何值,它设置了您的数组到null
。
我还注意到你的Html.BeginForm()
中没有任何帖子网址,但如果你说你可以检查调试中的值,我想你是以另一种方式做的...
答案 1 :(得分:0)
我希望user3426870是正确的,问题是EditVendor
方法签名(selectedTech
)上的名称与视图上的复选框名称不匹配(selectedTechs
)。我怀疑DefaultModelBinder
将无法匹配参数以将值绑定到。
此外,TryUpdateModel
似乎不包含将在您的帖子请求中传递的视图中定义的任何属性,因此我怀疑这不起作用。
我可以建议你做一些其他改进(你可以研究):
控制器方法非常大。你应该看看使用 服务/存储库,以执行任何业务逻辑和数据库 调用以减少控制器执行的操作数。 这将有助于使这些较小的部件更易于测试。
如果签名上的id不应该为null(如果它返回一个错误的请求),那么你不应该让它成为一个可以为空的int?参数。然后,您将不再需要执行该检查。
此外,您可能希望添加验证以确保id大于0或者selectedTech列表的计数大于0.这样的验证可以使用数据注释或流畅验证执行,然后简单检查在代码中执行,如:
if (ModelState.IsValid) { ... }
确保传入的参数通过您定义的验证。
希望这些想法有所帮助。