Ошибки dbvalidation EF Core2.0 не отображают все ошибки - PullRequest
0 голосов
/ 05 июля 2018

Я создал приложение EF core 2.0 и пытаюсь проверить модель в Savechanges, но она возвращает только первую ошибку проверки.

Вот мой 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();
    }

Класс

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 "требуется, и если я передаю firstname в объекте запроса, то требуется его возвращаемое" lastname ". Что я должен сделать, чтобы вернуть все ошибки, как мы это делаем в EF6, используя DbEntityValidationException?

1 Ответ

0 голосов
/ 05 июля 2018

Это потому, что 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)));
}

Тогда в вашем контроллере / действии вы можете явно обработать EntityValidationException:

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

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