Database First Validation

丶灬走出姿态 提交于 2020-01-03 16:09:07

问题


I have an auto-generated Entity Framework model. It was generated using a database first approach. The mid_initial column has a database defined constraint that limits the column to a maximum length of 3 characters.

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated from a template.
//
//    Manual changes to this file may cause unexpected behavior in your application.
//    Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Agency.DataAccess.RegistrationModel
{
    using System;
    using System.Collections.Generic;

    public partial class Registrant
    {
        public Registrant()
        {
        }

        public int id { get; set; }
        public string fname { get; set; }
        public string mid_initial { get; set; }
        public string lname { get; set; }
    }
}

When I try and create a model with a mid_initial greater than 3 characters, a invalid state, ModelState.IsValid is returning true. Because of this db.SaveChanges is then called, which then raises DbEntityValidationException.

[HttpPost]
public ActionResult Create(Registrant registrant)
{    
    try
    {
        if (ModelState.IsValid)
        {
            Debug.WriteLine("Entity was valid.");
            db.Registrants.Add(registrant);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View("Create", registrant);
    }
    catch (DbEntityValidationException e)
    {
        foreach (var eve in e.EntityValidationErrors)
        {
            Debug.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                eve.Entry.Entity.GetType().Name, eve.Entry.State);
            foreach (var ve in eve.ValidationErrors)
            {
                Debug.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                    ve.PropertyName, ve.ErrorMessage);
            }
        }
        return View(registrant);
    }
}

Why is the ModelState.IsValid method returning true? It would seem that my model is not aware of the maximum length constraint. How do I make it aware?


回答1:


EF db-first can't infer constraints from database.

Use the MaxLenght data annotation attribute:

public partial class Registrant
{
    public Registrant()
    {
    }

    public int id { get; set; }
    public string fname { get; set; }
    [MaxLength(3, ErrorMessage = "")]
    public string mid_initial { get; set; }
    public string lname { get; set; }
}

Note: this class is a auto generated class and every time you update and save your model (.EDMX file), this code will be overwritten and you'll loose your attributes.

To avoid that, you should extend your classes with some partial classes with the same name and same namespace as your auto-generated classes. If you need examples to show you how, tell me to put it in answer.




回答2:


MVC is EF-agnostic, and as such doesn't implicitly attempt to validate the model using EF validation to populate its ModelState.

You have four basic solutions I can think of right now:

  • Hook them up yourself, for example using MVC filters, DbContext.GetValidationErrors and ModelState.
  • Find and use third-party code that does this already.
  • Validate the code separately using facilities that MVC can use, for example using DataAnnotations. You may try to generate them automatically by modifying the EF T4 template. Note that this is still technically redundant (the code will be validated twice, once by MVC, once by EF).
  • Submit a patch for MVC so that it can support EF explicitly (as a soft dependency) and make it all just work (both projects are open source) -- or downvote me because they already did so and I never knew it.


来源:https://stackoverflow.com/questions/17951321/database-first-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!