Проверка не удалась для одного или нескольких объектов.См. Свойство EntityValidationErrors для более подробной информации.ASP.NET MVC - PullRequest
0 голосов
/ 15 октября 2018

Я столкнулся с ошибкой, отображаемой в качестве моего заголовка.Я пытался найти решения, но все, что я получил, это решение об использовании try catch блоков кода.

Я использовал документацию курса, которую я сделал, чтобы направлять меня в выполнении этого проекта, но ошибка, которую ястолкнулись с этим временем, я не знаю, какая часть пошла не так и как проверить не ту часть.

Есть две части, которые я прокомментировал с помощью // strange комментариев, что означает, что я понятия не имею, где происходит ошибка или что-то в этом роде.

Спасибо, что прочитали мой вопрос.

Это моя модель PetRescued

public class PetRescued
{
    public int Id { get; set; }

    [Required]
    [StringLength(255)]
    public string PetName { get; set; }

    public int PetAge { get; set; }

    [Required]
    [StringLength(6)]
    public string PetGender { get; set; }

    public short PetWeightInKg { get; set; }

    public DateTime DateWhenRescued { get; set; }

    public PetSpecies PetSpecies { get; set; }

    public byte PetSpeciesId { get; set; }

}

Это мой контроллер PetRescued

 public ActionResult New() //populate form
    {
        var petspecies = _context.PetSpecieses.ToList();

        var viewModel = new PetRescuedViewModel
        {
            PetSpecies = petspecies
        };

        return View("PetRescued", viewModel);
    }

[HttpPost]
public ActionResult Save(PetRescued petRescued)
{
    if (petRescued.Id == 0)
        _context.PetRescueds.Add(petRescued);
    else
    {
        var petRescuedInDb = _context.PetRescueds.Single(c => c.Id == petRescued.Id);
        petRescuedInDb.PetName = petRescued.PetName;
        petRescuedInDb.PetAge = petRescued.PetAge;
        petRescuedInDb.PetGender = petRescued.PetGender;
        petRescuedInDb.PetWeightInKg = petRescued.PetWeightInKg;
        petRescuedInDb.PetSpeciesId = petRescued.PetSpeciesId; //strange
        petRescuedInDb.DateWhenRescued = petRescued.DateWhenRescued;
     }

    _context.SaveChanges();
    return RedirectToAction("Index", "PetRescued");
}

Это моя PetRescued ViewModel

public class PetRescuedViewModel
{
    public IEnumerable<PetSpecies> PetSpecies { get; set; }

    public PetRescued PetRescueds { get; set; }


    public PetRescuedViewModel()
    {
        PetRescueds = new PetRescued(); 
    }
}

Это моя PetRescued форма

@using (Html.BeginForm("Save", "PetRescued"))
{
<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetName)
    @Html.TextBoxFor(m => m.PetRescueds.PetName, new { @class = "form-control" })
</div>

//strange
<div class="form-group">
    @Html.LabelFor(m => m.PetSpecies)
    @Html.DropDownListFor(m => m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new {@class = "form-control"})    
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetAge)
    @Html.TextBoxFor(m => m.PetRescueds.PetAge, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetGender)
    @Html.TextBoxFor(m => m.PetRescueds.PetGender, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetWeightInKg)
    @Html.TextBoxFor(m => m.PetRescueds.PetWeightInKg, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.DateWhenRescued)
    @Html.TextBoxFor(m => m.PetRescueds.DateWhenRescued, "{0:d MMM yyyy}", new { @class = "form-control" }) 
</div>

@Html.HiddenFor(m => m.PetRescueds.Id)
<button type="submit" class="btn btn-primary">Save</button>
}

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

Посмотрите на определение вашей модели

// This means this value is required 
// and should not be greater than 255 characters 
[Required]
[StringLength(255)]
public string PetName { get; set; }

// This means this value is required 
// and should not be greater than 6 characters 
[Required]
[StringLength(6)]
public string PetGender { get; set; }

Так что либо вы не отправляете значение из своего клиентского приложения, либо оно превышает указанные вами ограничения.Измените метод действия на этот, чтобы проверить свою модель в бэкэнде (никогда не доверяйте вводу клиента)

[HttpPost]
public ActionResult Save(PetRescued petRescued)
{
    if (ModelState.IsValid) // Check for errors
    {
        if (petRescued.Id == 0)
            _context.PetRescueds.Add(petRescued);
        else
        {
            var petRescuedInDb = _context.PetRescueds.Single(c => c.Id == petRescued.Id);
            petRescuedInDb.PetName = petRescued.PetName;
            petRescuedInDb.PetAge = petRescued.PetAge;
            petRescuedInDb.PetGender = petRescued.PetGender;
            petRescuedInDb.PetWeightInKg = petRescued.PetWeightInKg;
            petRescuedInDb.PetSpeciesId = petRescued.PetSpeciesId; //strange
            petRescuedInDb.DateWhenRescued = petRescued.DateWhenRescued;
         }

        _context.SaveChanges();
        return RedirectToAction("Index", "PetRescued");
    }
    else
        return View(petRescued); // Return the same view with the original data
                                 // or with the correct model of your view, at least
}

ОБНОВЛЕНИЕ

Исправьте модель представления так, чтобы она отражала ваши правильные данные.Это означает, что вы отправляете правильную модель на сервер.В ASP.Net MVC есть нечто, называемое привязка модели , которое представляет собой механизм, используемый для преобразования данных, полученных от клиента, в вашу модель C #.По умолчанию он работает путем определения имени значений, переданных клиентом, и определения точного сопоставления со свойствами модели.Это означает, что, по вашему мнению, вы объявляете это

    @Html.TextBoxFor(m => m.PetRescueds.PetName, new { @class = "form-control" })

Итак, если вы проверяете данные, отправленные браузером, вы увидите, что данные формы включают в себя что-то вроде

PetRescueds.PetAge: whatever_the_client_typed

не будет сопоставляться с вашей моделью, так как ваша модель не имеет свойства с именем PetRescueds с подпунктом PetName, ваша модель действия напрямую является моделью PetRescued.Поэтому либо измените свое представление, указав непосредственно имя attr, например,

    @Html.TextBox("PetName", Model.PetRescueds.PetName, new { @class = "form-control" })

, либо измените модель действия, чтобы она соответствовала определению модели представления.В любом случае, ваша модель представления должна быть последовательной в ваших действиях и представлении.В противном случае вы в конечном итоге получите нулевые значения в вашей модели действия, несмотря на то, что они правильно заполнены в вашем представлении или отображаются пустые значения в ваших представлениях независимо от того, что вы фактически создали в действии контроллера.

Итак, в основномпроверьте определения вашей модели.Убедитесь, что вы используете правильное определение модели для отображения в ваших представлениях.Убедитесь, что ваше представление правильно определено относительно того, что вы ожидаете получить в своем бэкэнд-контроллере.

Затем измените свое представление, включив в него ошибки проверки, полученные с сервера.

@using (Html.BeginForm("Save", "PetRescued"))
{
<!-- This will show your errors-->
@Html.ValidationSummary()
<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetName)
    <!-- Or you can show errors for each model property -->
    <!-- like this -->
    @Html.ValidationMessageFor(m => m.PetRescueds.PetName);
    @Html.TextBox("PetName", Model.PetRescueds.PetName, new { @class = "form-control" })
</div>

//strange
<div class="form-group">
    @Html.LabelFor(m => m.PetSpecies)
    @Html.DropDownListFor(m => m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new {@class = "form-control"})    
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetAge)
    @Html.TextBoxFor(m => m.PetRescueds.PetAge, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetGender)
    @Html.TextBoxFor(m => m.PetRescueds.PetGender, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetWeightInKg)
    @Html.TextBoxFor(m => m.PetRescueds.PetWeightInKg, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.DateWhenRescued)
    @Html.TextBoxFor(m => m.PetRescueds.DateWhenRescued, "{0:d MMM yyyy}", new { @class = "form-control" }) 
</div>

@Html.HiddenFor(m => m.PetRescueds.Id)
<button type="submit" class="btn btn-primary">Save</button>
}

Подробнее о проверке данных можно прочитать в Microsoft

.
0 голосов
/ 16 октября 2018

Вы должны использовать метод try и catch, чтобы увидеть, какие поля вызывают ' EntityValidationErrors ':

ActionResult Save =>

    try
    {
        _context.SaveChanges();;
    }
    catch (DbEntityValidationException ex)
    {
        var sb = new StringBuilder();

        foreach (var failure in ex.EntityValidationErrors)
        {
            sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());
            foreach (var error in failure.ValidationErrors)
            {
                sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                sb.AppendLine();
            }
        }

        throw new DbEntityValidationException(
            "Entity Validation Failed - errors follow:\n" +
            sb.ToString(), ex
            );
    }

Тогда вы будете знать, какие записи делают исключение.

0 голосов
/ 15 октября 2018

Давайте попробуем исправить это.

Сначала давайте изменим ваш контроллер, чтобы можно было что-то делать с ошибками, возвращаемыми связывателем модели.

[HttpGet]
public ActionResult New() //populate form
{
    var petspecies = _context.PetSpecieses.ToList();

    var viewModel = new PetRescuedViewModel
    {
        PetSpecies = petspecies
    };

    return View("PetRescued", viewModel);
}

[HttpPost]
public ActionResult Save(PetRescuedViewModel viewModel)
{
    if (ModelState.IsValid) // Check for errors
    {
        if (petRescued.Id == 0)
            _context.PetRescueds.Add(petRescued);
        else
        {
            var petRescuedInDb = _context.PetRescueds.Single(c => c.Id == petRescued.Id);
            petRescuedInDb.PetName = viewModel.PetRescued.PetName;
            petRescuedInDb.PetAge = viewModel.PetRescued.PetAge;
            petRescuedInDb.PetGender = viewModel.PetRescued.PetGender;
            petRescuedInDb.PetWeightInKg = viewModel.PetRescued.PetWeightInKg;
            petRescuedInDb.PetSpeciesId = viewModel.PetRescued.PetSpeciesId; //strange
            petRescuedInDb.DateWhenRescued = viewModel.PetRescued.DateWhenRescued;
        }

        _context.SaveChanges();
        return RedirectToAction("Index", "PetRescued");
    }

    viewModel.PetSpecies = _context.PetSpecieses.ToList();  // populate the list again as the contents are lost when the form is submitted.

    return View("PetRescued", viewModel); // validation errors found, so redisplay the same view
}

Затем измените ваше представлениеотображать ошибки.Мы в основном делаем то, что предлагает этот ответ.

@using (Html.BeginForm("Save", "PetRescued"))
{
    // Displays a summary of all the errors.
    @Html.ValidationSummary() 

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.PetName)
        @Html.TextBoxFor(m => m.PetRescueds.PetName, new { @class = "form-control" })
        // Or you can add this to each property            
        @Html.ValidationMessageFor(m => m.PetRescueds.PetName) 
    </div>

    //strange
    <div class="form-group">
        @Html.LabelFor(m => m.PetSpecies)
        @Html.DropDownListFor(m => m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new {@class = "form-control"})    
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.PetAge)
        @Html.TextBoxFor(m => m.PetRescueds.PetAge, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.PetGender)
        @Html.TextBoxFor(m => m.PetRescueds.PetGender, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.PetWeightInKg)
        @Html.TextBoxFor(m => m.PetRescueds.PetWeightInKg, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.DateWhenRescued)
        @Html.TextBoxFor(m => m.PetRescueds.DateWhenRescued, "{0:d MMM yyyy}", new { @class = "form-control" }) 
    </div>

    @Html.HiddenFor(m => m.PetRescueds.Id)
    <button type="submit" class="btn btn-primary">Save</button>
}

Вышеуказанные изменения как минимум покажут, какие свойства имеют проблему.

Следующим шагом будет решение проблемы.Если вы делаете вышеупомянутое и не можете понять это далее, дайте мне знать, какие это свойства, и я посмотрю.

Я предполагаю, что это public byte PetSpeciesId { get; set; }, но давайте посмотрим.

Надеюсь, это поможет.

...