EF Core2.0 dbvalidation 错误未显示所有错误

EF Core2.0 dbvalidation errors not displaying all errors

我创建了一个 EF 核心 2.0 应用程序并尝试在 Savechanges 上验证模型,但它只是 return 第一个验证错误。

这是我的 Dbcontext 和控制器

public partial class ProductWarehouseContext : DbContext
{  public List<string> ErrorList=new List<string>();
    public ProductWarehouseContext(DbContextOptions<ProductWarehouseContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Customer> Customer { get; set; }
    public virtual DbSet<Order> Order { get; set; }
    public virtual DbSet<OrderItem> OrderItem { get; set; }
    public virtual DbSet<Product> Product { get; set; }
    public virtual DbSet<Supplier> Supplier { get; set; }


    public override int SaveChanges()
    {
        var entities = from e in ChangeTracker.Entries()
            where e.State == EntityState.Added
                  || e.State == EntityState.Modified
            select e.Entity;


        foreach (var entity in entities)
        {
            var validationContext = new ValidationContext(entity);
            Validator.ValidateObject(
                entity,
                validationContext,
                validateAllProperties: true);
        }

        return base.SaveChanges();}
    }

控制器

[HttpPost]
    public IActionResult Save([FromBody]CustomerViewModel customer)
    {
        using (var cont = _context.Database.BeginTransaction())
        {
            try
            {
                var cust = new Customer()
                {
                    FirstName = customer.FirstName,
                    LastName = customer.LastName,
                    City = customer.City,
                    Country = customer.Country,
                    Phone = customer.Phone,
                    IsSubscribedforAlerts = customer.IsSubscribedforAlerts
                };

                _context.Customer.Add(cust);
                _context.SaveChanges();
                cont.Commit();
            }

            catch (Exception e)
            {
                Errors.Add(e.Message);
                cont.Rollback();
                foreach (var err in Errors)
                {
                    ModelState.AddModelError("errors", err);
                }
                return Ok(ModelState);
            }
        }
        return Ok();
    }

Class

public partial class Customer
{
    public Customer()
    {
        Order = new HashSet<Order>();
    }


    public int Id { get; set; }

    [Required(ErrorMessage = "FirstName is required to save a new customer")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "LastName is required to save a new customer")]
    public string LastName { get; set; }

    public string City { get; set; }

    public string Country { get; set; }

    [Required(ErrorMessage = "PhoneNumber is required to save a new customer")]
    public string Phone { get; set; }


    public bool? IsSubscribedforAlerts { get; set; }

    public ICollection<Order> Order { get; set; }
}

错误只是 returnig“"firstname" 是必需的,如果我在请求对象中传递名字,那么它的 returning "lastname" 是必需的。 我应该如何处理 return 所有错误我们如何使用 DbEntityValidationException 在 EF6 中做到这一点?

那是因为 ValidateObject() 在第一次遇到错误时抛出。尝试使用 TryValidateObject() 代替,并向其传递一个累积所有错误的 List<ValidationResult>

类似于:

public class EntityValidationException : Exception
{
    public EntityValidationException(IEnumerable<ValidationException> exceptions)
    {
        this.ValidationErrors = exceptions;
    }

    public IEnumerable<ValidationException> ValidationErrors { get; }
}

然后在你的 SaveChanges():

foreach (var entity in entities)
{
    var validationContext = new ValidationContext(entity);
    var validationResults = new List<ValidationResult>();

    Validator.TryValidateObject(entity, validationContext, validationResults);

    if (validationResults.Any())
        throw new EntityValidationException(validationResults.Select(x => new ValidationException(x, null, null)));
}

然后在你的 controller/action 中,你可以明确地处理 EntityValidationException:

catch (EntityValidationException validationException)
{
    foreach (var err in validationException.ValidationErrors)
    {
        var validationResult = err.ValidationResult;

        ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
    }
}