【问题标题】:i want to disable my custom validation in edit action in asp.net mvc我想在 asp.net mvc 的编辑操作中禁用我的自定义验证
【发布时间】:2017-05-10 12:40:26
【问题描述】:

型号

public partial class MemberModel 
    {

        [Key]
        public int MemberID { get; set; }

        [Required]
        [Unique_Member]
        [StringLength(255)]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }


        [Required]
        [Unique_Member]
        [StringLength(255)]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [Display(Name="Name")]
        public string FullName { get { return string.Format(FirstName + " " + LastName); } }

        [Required]
        [StringLength(355)]
        public string Address { get; set; }
        [Required(ErrorMessage="The City field is Required")]
        public int CityID { get; set; }

        [Required(ErrorMessage = "The Country field is Required")]
        public int CountryID { get; set; }


        [Required]
        [RegularExpression(@"^((0092))-{0,1}\d{3}-{0,1}\d{7}$|^\d{4}$|^\d{4}-\d{7}$", ErrorMessage = "Invalid Phone number")]
        [Unique_Member]
        public string Pin { get; set; }


        [Display(Name="Mobile No.")]
        [Required(ErrorMessage="Mobile No. Required")]
        [RegularExpression(@"^((\+92)|(0092))-{0,1}\d{3}-{0,1}\d{7}$|^\d{11}$|^\d{4}-\d{7}$",ErrorMessage="Invalid Phone number")]
        public string Phone { get; set; }


        [Required]
        [EmailAddress]
        public string Email { get; set; }


        public virtual List<Order_SummeryModel> Order_Summeries { get; set; }
        public virtual CountryModel Country { get; set; }
        public virtual CityModel City { get; set; }
    }

自定义验证 [Unique_Member]

它对我为创建新成员所做的三个属性“Pin”、“FirstName”和“LastName”进行了自定义验证。它检查新成员的全名和 pin 是否唯一。

它非常适合创建操作,但在编辑操作中这限制了我更新成员模型,我想禁用它以进行编辑操作,或者还有另一种方法可以通过禁用它来更新模型。

  public class Unique_MemberAttribute : ValidationAttribute
    {
        private static int count;

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            Context_getway db = new Context_getway();
            string membervalue = value.ToString();
            //var count = db.Members.Where((x => x.Name == membervalue || x.Pin == membervalue || x.Email == membervalue)).Count();
            var count_fname = db.Members.Where(x => x.FirstName == membervalue).Count();
            var count_lname = db.Members.Where(x => x.LastName == membervalue).Count();
            var count_pin = db.Members.Where(x => x.Pin == membervalue).Count();

            if ((count_fname != 0)||(count_lname != 0))
            {
                count++;
                if (count == 2)
                {
                    return new ValidationResult("Member Already Exist with the same Full Name (Change First Name OR Last Name)!");

                }
            }
            if (count_pin != 0)
            {
                return new ValidationResult("Member Already Exist with the same Pin!");
            }


                return ValidationResult.Success;

        }
    }
    [MetadataType(typeof(MemberModel))]
    public partial class MemberModel
    {

    }

成员控制器(编辑操作)

 [HttpGet]
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            else
            {
                var member = db.Members.Find(id);
                ViewBag.CountryID = new SelectList(db.CountryModels.ToList(), "CountryID", "Country",member.CountryID);
                ViewBag.CityID = new SelectList(db.CityModels.ToList(), "CityID", "City",member.CityID); 
                if (member != null)
                {
                    return View(member);
                }
                else
                    return HttpNotFound();
            }
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(MemberModel member)
        {

            try
            {  
                if (ModelState.IsValid)
                {
                    db.Entry(member).State = System.Data.Entity.EntityState.Modified;
                    db.SaveChanges();
                    TempData["Msg"] = "Update Successfully";
                    return RedirectToAction("Index");
                }
                else
                {
                    ViewBag.CountryID = new SelectList(db.CountryModels.ToList(), "CountryID", "Country",member.CountryID);
                    ViewBag.CityID = new SelectList(db.CityModels.ToList(), "CityID", "City",,member.CityID); 
                    return View(member);
                }
            }
            catch(Exception e)
            {
                TempData["Msg"] = "Update Unsuccessfully: "+ e.Message;
                return View();
            }
        }

【问题讨论】:

    标签: asp.net asp.net-mvc validation asp.net-mvc-4 asp.net-mvc-3


    【解决方案1】:

    试试这个:

    ModelState.Remove("PropertyNameInModel");
    

    【讨论】:

    • 'ModelState.Remove("FirstName"); ModelState.Remove("姓氏"); ModelState.Remove("Pin");' @codelover 我在编辑操作中添加了这三行,但它导致我出现另一个错误
    • 新错误是:没有类型为 'IEnumerable' 且具有键 'CityID' 的 ViewData 项。
    【解决方案2】:

    您仍然应该对 Edit 操作方法进行验证。否则,用户可以编辑一条记录并选择另一条记录已使用的唯一组合。您应该在 where 子句中简单地使用 Id 属性来检查除当前编辑记录之外的任何记录。

    所以第一步是获取您正在验证的当前实体/视图模型的 Id 属性值。然后在 where 子句中使用该值。

    protected override ValidationResult IsValid(object value, 
                                                      ValidationContext validationContext)
    {
        var idProperty = validationContext.ObjectType.GetProperty("MemberID");
        var idValueObj = idProperty.GetValue(validationContext.ObjectInstance, null);
        var id = 0;
        if (idValueObj != null)
            id = (int) idValueObj;
    
         var db = new Context_getway();
         string membervalue = value.ToString();
    
        var count_fname = db.Members.Count(x => x.FirstName == membervalue && x.UserId!=id);
        //Your existing code goes here. Make sure to use the id value in your WHERE clauses
    }
    

    我只是在答案中硬编码了属性名称(“MemberID”)来给你这个想法。但是如果你想要更多的灵活性,你可以在使用this answer中提到的属性时传递它。

    您还应该仔细检查您的条件。我发现你的代码有问题。如果您的count 变量值大于1(例如:2)),那么您的if (count == 2) 将不会返回true(因为您的count 大于2。我不确定您的业务需求/规则。但是,如果您正在寻找唯一的全名,您可以创建一个 LINQ 语句来执行此操作(使用 Any 方法而不是根据需要获取 Count)

    【讨论】:

    • 谢谢你的回答,我真的很感激,你说得对,我也应该在编辑视图中验证会员姓名,但是如果会员不想更改他的名字怎么办。
    • 然后你仍然执行你的代码。但是你的 where 子句现在有了新的东西(x.UserId!=id)。这意味着代码将检查该名称是否已用于另一条记录(它将排除当前正在编辑的记录)。
    【解决方案3】:

    一种方法是在编辑控制器操作中从 ModelState 中删除错误,就在检查模型是否有效之前。

    但更好的方法是将 Edit 和 Insert 模型分开。

    编辑模型将具有所有编辑验证规则;并且 Insert 模型将从 Edit 模型继承,并使用额外的验证规则覆盖一些属性。

    public partial class EditMemberModel 
    {
    
        [Key]
        public int MemberID { get; set; }
    
        [Required]
        [StringLength(255)]  // Removed the Unique_Member rule**
        [Display(Name = "First Name")]
        public virtual string FirstName { get; set; }
    
        /// etc.
    }
    
    
    public partial class InsertMemberModel : EditMemberModel
    {
        [Required]
        [Unique_Member]
        [StringLength(255)]
        [Display(Name = "First Name")]
        public override string FirstName { get; set; }
    
        /// etc.
    }
    

    【讨论】:

    • 但它给出了一个错误:无法覆盖继承的成员
    • 尝试将基础模型中的属性定义为虚拟属性。
    • 抱歉打扰您,但现在更新时出现此错误没有具有键“CityID”的“IEnumerable”类型的 ViewData 项。跨度>
    • 您是否在这一行中遇到了该错误? ViewBag.CityID = new SelectList(db.CityModels.ToList(), "CityID", "City",member.CityID);
    • 是的,我在基类中有 CityID 和必填字段。
    猜你喜欢
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多