我在向人员证明申请时遇到一些麻烦,因此它只能提交有效信息并告诉用户如果没有错误。
我希望控制器创建的新属性(新的联系人)在表单回发时通过不引人注目的JS验证为false。
重要 -
这是使用BeginCollectionItem
动态添加和删除属性Contact
中的cmp.contacts (List<Contact>)
个对象。
这些属性是必需的,但可以从表单中删除。提交后,控制器会检查它们,如果没有,则将它们重新添加到表单中。
由于刚刚添加了属性,它们在技术上并非无效。
更新 - 进一步调查
然而,这确实很奇怪,因为我已经制作了&#34;&#34;由于要求字符长度至少为3,因此字符串值无效,在模型中设置。所以在回发后的控制器中,我检查列表是否为空(如果用户已将其删除)并创建一个新列表,然后通过ModelState.IsValid
检查,它通过了。联系人的属性是字符串值&#34;&#34;这应该是无效的,但是在第二篇文章回来之前它并没有被标记为无效,为什么会这样?
示例故事:
用户从页面中删除联系人列表(您可以拥有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; }
}
答案 0 :(得分:1)
您需要创建自己的ValidationContext
来验证新的Contact
对象,并将结果添加到ModelState
if (cmp.contacts == null || !cmp.contacts.Any())
{
var newContact = new Contact(); // no need to set the values to empty strings
cmp.contacts = new List<Contact>{ newContact };
// validate
var context = new ValidationContext(newContact);
var results = new List<ValidationResult>();
Validator.TryValidateObject(newContact, context, results);
// add errors to ModelState
foreach(var result in results)
{
var propertyName = string.Format("contacts[0].{0}", result.MemberNames.First());
ModelState.AddModelError(propertyName, result.ErrorMessage);
}
return View(cmp);
}
答案 1 :(得分:0)
您可以使用ValidateModel()
或TryValidateModel()
,如下所示
if (cmp.contacts == null)
cmp.contacts = new List<Contact>{
new Contact { email = "", name = "", telephone = "" }
};
foreach(Contact cont in cmp.contacts){
if(!TryValidateModel(cont)){
ModelState.AddModelError("", "An Invalid Contact Were Found!");
// return View(cmp); or
return View("InvalidContact",cont);
//you need to create a view nammed InvalidContact to provide more validation error messages
}
}
InvalidContact.cshtml
@model proj.Models.Contact
@Html.ValidationSummary(true)
<div class="col-md-10">
<div class="input-group">
@Html.TextBoxFor(m => m.telephone , new { @class = "form-control", placeholder = "telephone " })
@Html.ValidationMessageFor(m => m.telephone )
</div>
</div>...
答案 2 :(得分:0)
不幸的是,我试过并且未能得到我想要的结果,在回发后验证,但结果却过于复杂。
这更好(更简单),与我想象的更多人的问题更相关 - 感谢Stephen的讨论和建议。
如果长度仅为1,则删除删除按钮的简单jQuery。
var conLen = $('#editorRowsContact .editorRow').length;
if (conLen == 1) {
$('#editorRowsContact .editorRow .deleteRow').remove();
}