提交表单

时间:2018-04-18 15:22:15

标签: c# asp.net-mvc-5

好吧我已经解决了这个问题2天了。为简单起见,我会尽可能少地编写代码 我使用相同的控制器来查看和保存数据。我的域类,视图,控制器如下(我对最后一个道具public DateTime CreatedOn有问题,最后解释了整个问题,所以你可以先跳到它):

域类:

public partial class Admin_TestCategory
{
    [Key]
    [Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public short TestCategoryId { get; set; }

    [StringLength(100)]
    [Column(Order = 1)]
    [Required]
    public string TestCategoryName { get; set; }

    [Column(Order = 2)]
    public int? CreatedBy { get; set; }

    [Column(Order = 3)]
    public DateTime CreatedOn { get; set; }
}  

查看:

@model BOL.Entities.Admin.Admin_TestCategory
@{
    ViewBag.Title = "Edit Category";
    Layout = "~/Views/Admin/_Admin.cshtml";
}
@using (Html.BeginForm("EditTestCategory", "Admin", FormMethod.Post))
{
    <div class="row">
        <div class="col-lg-12">
            <fieldset>
                <legend>Edit Category</legend>
                <div class="form-group row">
                    @Html.HiddenFor(m => m.TestCategoryId)
                    @Html.LabelFor(m => m.TestCategoryName, "Category Name :", new {@class = "col-lg-2"})
                    @Html.TextBoxFor(m => m.TestCategoryName, new {@class = "col-lg-3 form-control"})
                    <div class="col-lg-1"></div>
                    @Html.LabelFor(m => m.CreatedBy, "Created By :", new {@class = "col-lg-2"})
                    @Html.TextBoxFor(m => m.CreatedBy, new {@class = "col-lg-3 form-control"})
                </div>
                <div class="form-group row">
                    <div class="col-lg-6">
                        <button type="submit" class="btn btn-primary form-group col-lg-2">Update</button>
                    </div>
                    <div class="col-lg-6">
                        <div class="row">
                            @Html.LabelFor(m => m.CreatedOn, "Created On :", new {@class = "col-lg-4"})
                            @Html.TextBoxFor(m => m.CreatedOn, "{0:dd-MM-yyyy}", new {Name = Html.NameFor(m => m.CreatedOn), @class = "col-lg-6 form-control datepicker" })
                        </div>
                    </div>
                </div>
            </fieldset>
        </div>
    </div>
}  

和控制器:

    // GET /Admin/EditTestCategory
    [HttpGet]
    public ActionResult EditTestCategory(Admin_TestCategory newTestCategory)
    {
        var testCatService = new TestCategoryService();
        var oldTestCategory = testCatService.GetById(newTestCategory.TestCategoryId);

        //check if that category exists or not
        //category does not exist
        if (oldTestCategory == null)
            return HttpNotFound("Can not find the ID of the given Test Category");

        //category exists
        return View(oldTestCategory);
    }

    // POST /Admin/UpdateTestCategory
    [HttpPost]
    public ActionResult UpdateTestCategory(Admin_TestCategory newTestCategory)
    {
        var testCatService = new TestCategoryService();
        var oldTestCategory = testCatService.GetById(newTestCategory.TestCategoryId);

        //check if that category exists or not
        //category does not exist
        if (oldTestCategory == null)
            return HttpNotFound("Can not find the ID of the given Test Category");

        //category exists
        //check if the new data is changed or not
        //data is not changed
        var o = JsonConvert.SerializeObject(oldTestCategory);
        var n = JsonConvert.SerializeObject(newTestCategory);
        if (o == n)
            return RedirectToAction("TestCategory", "Admin");

        //data is changed
        testCatService.UpdateTestCategory(newTestCategory);
        return RedirectToAction("TestCategory", "Admin");
    }  

控制器的工作方式全部都带有注释。它的工作方式是,当第一次触发该控制器时,它只有id属性,然后它将使用该属性获取其他数据并填充View。然后当我点击我的视图按钮时,该控制器的参数将包含所有已更改的数据,因此它将更新数据库。唯一的问题是当控制器第二次被击中时,它通过模型绑定获得所有其他数据,但只有最后一个CreatedOnDateTime。我提供Name属性以确保它绑定模型,但它没有,在控制器中日期会重置,尽管在浏览器中我检查过它,是的,它具有所需的确切名称。

我尝试制作此表单POST,尝试在我的域类的DateTime道具中添加属性[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")],但它不起作用,因为在视图中它是TextBoxFor我需要这种方式进行自动验证。那么我还应该尝试什么呢?

更新

我已将控制器拆分为2,一个用于使用GET另一个显示所有数据,以使用POST更新所有数据。还是同样的问题。

2 个答案:

答案 0 :(得分:1)

将以下代码添加到您的Post操作中,这将有助于找出导致错误的字段。

我尝试在我的机器上执行你的代码,似乎错误的“日期”格式。尝试使用"{0:MM/dd/yyyy}";在您的代码中格式化它将解决您的错误。

   foreach (ModelState modelState in ViewData.ModelState.Values)
   {
      foreach (ModelError error in modelState.Errors)
      {
        var errorMsg = error.ErrorMessage;
      }
   }

快乐编码:)

已更新:在ur model属性中添加DisplayFormat属性,因为它在您的视图代码中

答案 1 :(得分:0)

根据评论,您需要单独的GET和POST操作。在获取操作上,您需要找到要编辑的项目并将其作为视图模型返回:

 public ActionResult EditTestCategory(short id)
    {
        var testCatService = new TestCategoryService();
        var categoryToEdit = testCatService.GetById(id);

        //check if that category exists or not
        //category does not exist
        if (categoryToEdit == null)
            return HttpNotFound("Can not find the ID of the given Test Category");

        return View(categoryToEdit);
    }

然后你需要一个接受编辑模型的POST动作,如下所示:

 [HttpPost]
    public ActionResult EditTestCategory(Admin_TestCategory viewModel)
    {
        var testCatService = new TestCategoryService();
        Admin_TestCategory categoryToEdit = testCatService.GetById(viewModel.TestCategoryId);

        if(ModelState.IsValid)
        {
            categoryToEdit.TestCategoryName = viewModel.TestCategoryName;
            categoryToEdit.CreatedBy = viewModel.CreatedBy;
            //etc
            testCatService.UpdateTestCategory(categoryToEdit);

        }

        return RedirectToAction("TestCategory", "Admin");
    }

你遇到的另一个问题是CreatedBy是数据类型int吗?在Admin_TestCategory.cs

在您看来,您正在使用:

@Html.TextBoxFor(m => m.CreatedBy, new { @class = "col-lg-3 form-control" })

如果您更改为:

@Html.EditorFor(m => m.CreatedBy, new { @class = "col-lg-3 form-control" })

模型绑定良好