MVC4编辑post方法不保存

时间:2014-11-27 18:04:54

标签: c# asp.net-mvc-4 razor

我是asp.net MVC4的新手,我有一个使用SQL Server 2012 EntityFramework(代码优先)的MVC4应用程序。 Edit post方法不保存数据。在检查ModelState.IsValid是否返回false时,任何人都可以帮我找到我的代码错误

MODEL

public class Customer
    {
        [Key]
        public int Id { get; set; }
    [Required(ErrorMessage="*")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "*")]
    public string LastName { get; set; }

    [Required(ErrorMessage = "*")]
    [MaxLength(1, ErrorMessage="Initial only")]
    public string MI { get; set; }

    [Required(ErrorMessage = "*")]
    public string Address { get; set; }

    [Required(ErrorMessage = "*")]
    public String ContactNo { get; set; }

    [Required(ErrorMessage = "*")]
    [DataType(DataType.EmailAddress, ErrorMessage = "Invalid Email")]
    public string EmailAddress { get; set; }

    [Required(ErrorMessage = "*")]
    [MaxLength(8, ErrorMessage = "Max of 8")]
    [MinLength(5, ErrorMessage = "Min of 5")]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    [NotMapped]
    public string Password { get; set; }

    [Required(ErrorMessage = "*")]
    [DataType(DataType.Password)]
    [NotMapped]
    [Display(Name = "Retype-PW")]
    public string RetypePassword { get; set; }

    [Required]       
    [Display(Name = "How much is")]
    [NotMapped]
    public string Captcha { get; set; }
}

编辑视图

<h2>Edit CUSTOMER</h2>
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Customer</legend>

        @Html.HiddenFor(model => model.Id)
        @Html.HiddenFor(model=>model.Captcha)
        @Html.HiddenFor(model=>model.Password)
        @Html.HiddenFor(model=>model.RetypePassword)

        <div class="editor-label">
            @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.MI)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.MI)
            @Html.ValidationMessageFor(model => model.MI)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Address)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Address)
            @Html.ValidationMessageFor(model => model.Address)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ContactNo)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ContactNo)
            @Html.ValidationMessageFor(model => model.ContactNo)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.EmailAddress)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.EmailAddress)
            @Html.ValidationMessageFor(model => model.EmailAddress)
        </div>        
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

编辑控制器方法

public ActionResult Edit(int id = 0)
        {
            Customer customer = db.Customers.Find(id);
            if (customer == null)
            {
                return HttpNotFound();
            }
            return View(customer);
        }

        //
        // POST: /Customer/Edit/5

        [HttpPost]
        public ActionResult Edit(Customer customer)
        {
            if (ModelState.IsValid)
            {
                db.Entry(customer).State = EntityState.Modified;
                db.SaveChanges();
                if (User.IsInRole("Administrator"))
                {
                    return RedirectToAction("Index");
                }
                else
                {
                    return RedirectToAction("Details");
                }

            }
            return View(customer);
        }

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

@Html.HiddenFor(model=>model.Captcha)
@Html.HiddenFor(model=>model.Password)
@Html.HiddenFor(model=>model.RetypePassword)

这条线路不安全,它可能同时查看控制台中的内容可能不是密码的好价值你做了8个字符限制但是你读了bd中的值,我希望这个值是cripted!,你写一个代码到8更多char,模型不是有效的,尝试在控制台中读取这个冠军的值,并与你的设置进行比较。

您使用相同模型创建和编辑的问题,以及编辑是否需要captha和pasword,选项是其他模型,设置不需要,检查创建或编辑模式是否需要设置,

答案 1 :(得分:0)

  

帮我找到我的代码错误

  • 您正在使用脚手架@Html.ValidationSummary(true)true传递hidePropertyErrors。如果您的编辑表单显示模型的每个属性的编辑器,那么这很好,但如果没有,您的页面将显示哪些ModelState错误阻止了成功处理。将true更改为false以查看所有错误。
  • 您正在使用实体框架模型作为ViewModels。
  • 您允许进行大规模分配。
  • 您未使用跨站点请求伪造令牌。

您刚刚遇到了一个主要案例,该案例说明了您应该使用ViewModel的原因。一种解决方案是删除您不希望看到有问题的属性的模型错误。

像:

ModelState.Remove("Captcha");
ModelState.Remove("Password");
ModelState.Remove("RetypePassword");

if (ModelState.IsValid)
{
    // your code ...

但这会导致您的模型更新为空密码 null,因为您没有提供编辑器的属性,您不想要这些属性无论如何都会失败。因此,您需要加载现有实体并进行更新:

ModelState.Remove("Captcha");
ModelState.Remove("Password");
ModelState.Remove("RetypePassword");

if (ModelState.IsValid)
{
    var existingCustomer = db.Customers.First(c => c.ID == customer.ID);

    // Update properties of attached entity
    existingCustomer.FirstName = customer.FirstName;
    existingCustomer.LastName = customer.LastName;
    // and so on...

要避开大部分这种笨拙,只需定义一个ViewModel:

public class EditCustomerModel
{
    [Required(ErrorMessage="*")]
    public string FirstName { get; set; }

    [Required(ErrorMessage="*")]
    public string LastName { get; set; }

    // and so on...
}

然后在你的动作方法中将如下所示:

public ActionResult Edit(EditCustomerModel customer)
{
    if (ModelState.IsValid)
    {
        var existingCustomer = db.Customers.First(c => c.ID == customer.ID);

        // Update properties of attached entity
        existingCustomer.FirstName = customer.FirstName;
        existingCustomer.LastName = customer.LastName;

        db.SaveChanges();

        return RedirectToAction(...);
    }

    return View();
}

答案 2 :(得分:0)

我使用了CodeCaster第二个建议,但它没有用,但是当我在我的视图中为我的3个未映射字段(Captcha,密码,retypepassword)添加隐藏输入并分配默认值时,它现在可以正常工作。

<input type="hidden" id="Captcha" name="Captcha" value="Captcha" />
<input type="hidden" id="Password" name="Password" value="Password" />
<input type="hidden" id="RetypePassword" name="RetypePassword" value="RetypePassword" />