HTTP Post没有返回字符串数组

时间:2014-04-13 13:31:05

标签: asp.net-mvc asp.net-mvc-4 razor http-post

我正在使用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值。

2 个答案:

答案 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) { ... }

确保传入的参数通过您定义的验证。

  • 您应该使用视图模型来准确保存视图 您需要的信息。然后,您可以在此与您之间进行映射 使用映射类(或者automapper)的低层业务类。 使用视图模型是首选方法,避免使用ViewBag 属性。您还可以使用一些HTML帮助程序方法 写出一些视图模型属性。

希望这些想法有所帮助。