MVC3编辑模型忽略了setter逻辑

时间:2013-03-11 17:19:55

标签: c# asp.net-mvc-3 entity-framework validation

我正在使用ASP.NET MVC 3和实体框架来构建一个小应用程序。

我有一个代表社交活动的模型,该活动有“最多参加人数”和“当前注册的与会者”。编辑事件时,用户可以更改事件的容量,但我想阻止他们将容量更改为低于当前注册人数的值。

我天真地假设我可以在我的事件模型中将此逻辑添加到我的setter中的Capacity属性,但似乎忽略了这个逻辑并且值仍然会更新......

以下是完整更新的模型:

public class SocialEvent : IValidatableObject
{
    public SocialEvent()
    {
        this.Users = new HashSet<Person>();
    }


    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Date { get; set; }

    public int Capacity { get; set; }

    public int SlotsRemaining { get { return Capacity - Attending; } }
    public int Attending { get { return Users.Count; } }

    public virtual ICollection<Person> Users { get; set; }


    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Capacity < Attending)
        {
            var campo = new[] { "Capacity" };
            yield return new ValidationResult("Capacity cannot be less than number of confirmed attendees.", campo);
        }
    }
}

这是我的控制器的代码,这主要是自动生成的东西,我猜这是问题所在:

    //
    // GET: /Event/Edit/5
    public ActionResult Edit(int id)
    {
        SocialEvent socialevent = db.SocialEvents.Find(id);
        return View(socialevent);
    }

    //
    // POST: /Event/Edit/5
    [HttpPost]
    public ActionResult Edit(SocialEvent socialevent)
    {
        if (ModelState.IsValid)
        {
            db.Entry(socialevent).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(socialevent);
    }

这是我的视图,其中包含用于编辑模型的字段:

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
    <legend>NadEvent</legend>

    @Html.HiddenFor(model => model.Id)


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

    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>
}

这里最好的解决方案是什么,在设置容量时如何添加自己的逻辑以防止用户选择无效的数字?感谢。

1 个答案:

答案 0 :(得分:0)

当您使用ModelState规则与模型中定义的DataAnnotations相关时,您不能做出这样的假设,在您的情况下,您需要实现接口的验证类型IValidatableObject并覆盖方法Validate,因此可以定义需要执行的自定义服务器端验证

例如

public class SocialEvent : IValidatableObject
{
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if(Capacity < Attending)
        {
           var campo = new[] { "Capacity" }; 
           yield return new ValidationResult("Capacity cannot be less than number of confirmed attendees.", campo);  
        }
    }

}

当您在mvc中工作时,您可以使用此注释定义一些"automatic"验证,例如

[Required] <--- this forces in the view to be a required field
public string email {get ; set;}

In this link you cand find all the DataAnnotations that you can use in your models Also in this link您可以看到此数据注释的一些示例

上次更新

默认情况下,您没有填写Attending字段值,因为用户的ICollection它是空的,第二个即使这是有效的,开始时你应该考虑将字段添加为隐藏值,当你点击Windows应序列化该字段,您可以使用值

修改编辑视图添加参加字段

@Html.HiddenFor(model => model.Attending)

填写ICollection<Uers>,因为您无法获得参与值中的值,请检查linq和您的数据库生成的查询,看看它们是否相关。