【发布时间】:2015-09-28 13:32:34
【问题描述】:
我在让我的请求表进行人员证明时遇到了一点麻烦,所以它只能提交有效信息并告诉用户如果没有则错误是什么。
我希望控制器创建的新属性(新联系人)在表单回发时被不显眼的 JS 验证为 false。
重要 -
这是使用BeginCollectionItem 从属性cmp.contacts (List<Contact>) 动态添加和删除Contact 对象。
这些属性是必需的,但可以从表单中删除。提交后,控制器会检查它们,如果不存在,它会将它们重新添加到表单中。
由于刚刚添加的属性,它们在技术上并不无效。
更新 - 进一步调查
但是,这看起来确实很奇怪,因为我已将 "" 作为字符串值无效,因为在模型中设置的字符长度至少为 3。所以在回发的控制器中,我检查列表是否为空,它是(如果用户已删除它)并创建一个带有新联系人的新列表,然后通过ModelState.IsValid 检查,它通过。联系人的属性是“”的字符串值,应该是无效的,但直到第二次回帖才将它们标记为无效,这是为什么呢?
示例故事:
用户从页面中删除联系人列表(您可以有 1 个以上的联系人),提交表单,表单失败,因为它至少需要一个联系人。控制器创建一个新联系人并将表单发送回表单。页面显示有联系人属性,但由于是新创建的,并不无效。
如果用户尝试再次提交它们,它们将被标记为无效,但我希望用户需要填写的内容非常明显。
我可以在回发时将它们设置为无效吗?
带有问题字段的部分视图:
@model Contact
<div class="editorRow">
@using (HtmlHelpers.BeginCollectionItem.HtmlPrefixScopeExtensions.BeginCollectionItem(Html, "contacts"))
{
<div class="ui-grid-c ui-responsive">
<div class="ui-block-a">
<span>
@Html.TextBoxFor(m => m.name)
</span>
</div>
<div class="ui-block-b">
<span>
@Html.TextBoxFor(m => m.telephone)
</span>
</div>
<div class="ui-block-c">
<span>
@Html.TextBoxFor(m => m.email)
</span>
</div>
<div class="ui-block-d">
<span>
@Html.DropDownListFor(m => m.type, new List<SelectListItem>
{
new SelectListItem { Text = "Admin", Value = "Admin" },
new SelectListItem { Text = "Peer", Value = "Peer" },
new SelectListItem { Text = "Technical", Value = "Technical" }
})
<span class="dltBtn">
<a href="#" class="deleteRow">
<img src="~/Images/DeleteRed.png" style="width: 15px; height: 15px;" />
</a>
</span>
</span>
</div>
</div>
}
</div>
控制器
public ActionResult Create()
{
var cmp = new Company
{
contacts = new List<Contact>
{
new Contact { email = "", name = "", telephone = "", type = "" }
}
};
return View(cmp);
}
[ValidateAntiForgeryToken]
public ActionResult Create(Company cmp)
{
if (ModelState.IsValid)
{
db.companys.Add(cmp);
db.SaveChanges();
EmailSupport.SendEmail(cmp, "Request Form");
return RedirectToAction("Thankyou", "Home");
}
if (cmp.contacts == null)
cmp.contacts = new List<Contact>
{
new Contact { email = "", name = "", telephone = "" } // this row of properties to show required
};
return View(cmp);
}
型号
[Table("Company")]
public class Company
{
[Key]
public int companyId { get; set; }
[Required(ErrorMessage="Company name required.")]
public string name { get; set; }
[Required(ErrorMessage = "Telephone required.")]
public string telephone { get; set; }
[Required(ErrorMessage="Registration Number required.")]
public string regNumber { get; set; }
[EnsureOneItem]
public List<Contact> contacts { get; set; }
}
[Table("Contact")]
public class Contact
{
[Key]
public int contactId { get; set; }
public int companyId { get; set; }
[ForeignKey("companyId")]
public Company company { get; set; }
[Required(ErrorMessage="Contact name required.")]
public string name { get; set; }
[Required(ErrorMessage="Telephone required.")]
public string telephone { get; set; }
[Required]
[RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
@"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
@".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$",
ErrorMessage = "Email is not valid.")]
public string email { get; set; }
[Required(ErrorMessage = "Contact type required.")]
public string type { get; set; }
}
【问题讨论】:
-
@StephenMuecke
if(cmp.contacts == null)不会失败,当调试集合为空时,不确定为什么或我在其他实现领域做错了什么。我已经更新了这个问题,并将通过进一步的调查继续这样做 - 我已经从我的控制器中包含了 create 方法,我将cmp对象传递给页面。删除contacts (List<Contact>)的唯一行会使contactsnull而不是 POST 上的空集合。 -
刮掉我的最后一条评论。
TryUpdateModel()不起作用,因为新的Contact的值不在请求中。您将需要创建一个新的ValidationContext。我会尽快添加答案 -
谢谢 - 你能否解释一下为什么当我在控制器中实例化
null并将对象传递给表单时,我将其返回为List<Contact>,然后将其序列化为 html 为根据我的理解,并在提交时发回 - 如果至少有contacts[0]联系人在发布时不会是null。 -
在您的情况下您将获得
null,因为您没有在Contact的构造函数中初始化集合。但是这样做很典型,所以我建议还测试cmp.contacts是否包含任何项目
标签: c# jquery asp.net-mvc validation