【问题标题】:MVC3 Editing model ignores setter logicMVC3 编辑模型忽略设置器逻辑
【发布时间】:2013-03-11 17:19:55
【问题描述】:

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

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

我天真地假设我可以将此逻辑添加到我的事件模型中的容量属性的设置器中,但似乎此逻辑被忽略并且值无论如何都会更新...

这是完整的更新模型:

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>
}

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

【问题讨论】:

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


    【解决方案1】:

    不,当您使用 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 是空的,其次,即使这有效,并且开始时您应该考虑将该字段添加为隐藏值,当您在窗口中单击时,您应该序列化你可以有值的字段

    修改了您的编辑视图,添加了出席字段

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

    填写ICollection&lt;Uers&gt;,因为你无法获取主值中的值检查linq生成的查询和你的数据库,看看是否相关。

    【讨论】:

    • 谢谢,这很有帮助...我还有一些其他属性未包含在原始帖子中以节省空间,包括日期字段。如果我要覆盖 Validate 函数,我现在是否必须手动验证所有这些字段?
    • 给我两分钟的时间来解释一下关于 DataAnnotations 的更多信息
    • 谢谢。我现在发现“参加”显示为 0,即使它绝对不是 0。知道为什么会这样吗?它在视图中显示“参加”的正确值,但是当我进入“验证”方法时,它的值为 0。抱歉,如果这没有足够的信息。
    • 这似乎与“参加”属性只是返回“用户”列表中的“计数”属性有关,并且由于某种原因它显示用户列表为空,但仅在这种情况下。在应用程序的其他任何地方,它都能正确检索该号码。我的“用户”类是否需要实现某种接口才能与此 Validate 方法正确交互?
    • 您是否修改了模型?如果你这样做了,用新模型更新你的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多