ASP.Net MVC 4自定义验证属性isValid被调用两次

Joe*_* 89 3 c# asp.net validation asp.net-mvc asp.net-mvc-4

我正在尝试创建一个示例验证属性,以了解有关MVC的更多信息。我已经创建了验证属性,但是在运行应用程序时,两次调用了验证属性->在调用控制器之前和在保存DBContext之前。我相信这应该只调用一次。你能指导我我在哪里做错了。

验证属性:我正在尝试验证属性中的单词是否比指定的maxWords太多

public class ValidationEx : ValidationAttribute
    {
        int _maxWords = 1;
        public ValidationEx()
            : base("{0} has more too many words")
        {
            _maxWords = 1;
        }

        public ValidationEx(int maxWords):base("{0} has more too many words")
        {
            _maxWords = maxWords;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                string data = value as string;
                if (data.Split(' ').Length > _maxWords)
                {
                    var errorMessage = FormatErrorMessage(validationContext.DisplayName);
                    return new ValidationResult(errorMessage);
                }
            }
            return ValidationResult.Success;
        }
    }
Run Code Online (Sandbox Code Playgroud)

控制器:

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Album album)
        {
            if (ModelState.IsValid)
            {
                db.Albums.Add(album);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.GenreID = new SelectList(db.Genres, "GenreID", "Name", album.GenreID);
            ViewBag.ArtistID = new SelectList(db.Artists, "ArtistID", "ArtistName", album.ArtistID);
            return View(album);
        }
Run Code Online (Sandbox Code Playgroud)

注意:在到达控制器之前和执行db.SaveChanges()时会触发验证。

模型:

 public class Album
    {
        public virtual int AlbumID { get; set; }
        public virtual int GenreID { get; set; }
        public virtual int ArtistID { get; set; }

        [Required(ErrorMessageResourceType= typeof(ErrorMessages), ErrorMessageResourceName="TitleRequired")]
        [Display(Name="Movie Name")]
        [ValidationEx()]
        public virtual string Title { get; set; }

        [Range(0,1000)]
        public virtual decimal Price { get; set; }
        public virtual string AlbumArtUrl { get; set; }
        public virtual Genre Genre { get; set; }
        public virtual Artist Artist { get; set; }

        [StringLength(40)]
        public virtual string Description { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

数据库上下文

public class MusicAlbumStoreDBContext : DbContext
    {
        // You can add custom code to this file. Changes will not be overwritten.
        // 
        // If you want Entity Framework to drop and regenerate your database
        // automatically whenever you change your model schema, add the following
        // code to the Application_Start method in your Global.asax file.
        // Note: this will destroy and re-create your database with every model change.
        // 
        // System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<MusicAlbumProject.Models.MusicAlbumStoreDBContext>());

        public MusicAlbumStoreDBContext() : base("name=MusicAlbumStoreDBContext")
        {
        }

        public DbSet<Album> Albums { get; set; }

        public DbSet<Genre> Genres { get; set; }

        public DbSet<Artist> Artists { get; set; }

        public DbSet<Order> Orders { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

ViR*_*iTy 5

您正在使用与模型和视图模型相同的类。这是MVC在这两种类型之间不一致的原因。您确实应该添加一个单独的模型和一个单独的视图模型类。

IsValid() 被叫了两次

  1. 在控制器动作之前,因为在调用动作之前验证了数据
  2. db.SaveChanges()之所以继续,是因为数据库上下文也进行了验证