c# - 对 PostBack 创建的类进行不显眼的验证

标签 c# jquery asp.net-mvc validation

我在证明我的请求表单时遇到了一些麻烦,因此它只能提交有效信息并告诉用户什么是错误的,如果不是的话。

我希望 Controller 创建的新属性(新联系人的属性)在表单回发时被不显眼的 JS 验证为 false。

重要- 这是使用 BeginCollectionItem添加和删​​除 Contact来自属性(property)的对象 cmp.contacts (List<Contact>)动态地。

这些属性是必需的,但可以从表单中删除。提交后, Controller 会检查它们,如果不存在,则会将它们重新添加到表单中。

由于刚刚添加的属性,它们在技术上不是无效的。

更新 - 进一步调查

但是,这看起来确实很奇怪,因为我已将 ""作为字符串值无效,因为在模型中设置的字符长度至少为 3。因此,在回发的 Controller 中,我检查列表是否为空(如果用户已将其删除)并创建一个包含新联系人的新列表,然后通过 ModelState.IsValid检查,它通过了。联系人的属性是 ""的字符串值,这应该是无效的,但直到第二次回发时才将它们标记为无效,这是为什么?

示例故事:

用户从页面中删除联系人列表(您可以有 1 个以上的联系人),提交表单,表单失败,因为它至少需要一个联系人。 Controller 创建一个新的联系人并将表单发送回表单。页面上显示有联系人属性,但因为是新创建的,所以不是无效的。

如果用户尝试再次提交它们,它们将被标记为无效,但我希望用户需要填写的内容非常明显。

我可以在回发时将它们设置为无效吗?

带有问题字段的部分 View :

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

Controller

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

最佳答案

您需要创建自己的 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);
}

关于c# - 对 PostBack 创建的类进行不显眼的验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32824371/

相关文章:

asp.net-mvc - 将 Unity 与 Web Api 2 一起使用给出错误没有默认构造函数

jquery - 帮我理解这一行 jQuery

asp.net-mvc - asp.net mvc 局部 View 错误出

c# - 请求在 Helper 方法上被中止 : The connection was closed unexpectedly.

c# - Elmah 不过滤/拦截 web api 上的错误

javascript - 在 IE 11 中动态创建对象键(预期标识符、字符串或数字,不是逗号问题)

jQuery 和 AJAX?

c# - 如何获取 StackPanel 的句柄?

c# - Geolocation.CivicAddress.City 返回空的 win8 metro 应用程序

c# - 使用反射解析函数/方法内容