none
DataAnnotations with EntityFramework (Database First) method RRS feed

  • Question

  • I have a project in which I have a database model class provided along with a separate EDMX EF model. In the same solution, I have a web service which accesses this project along with the model class. I want the model class to perform data annotions against the front end for validation, but is not getting validated at all.

    For brevity, the model class (in my Model project) is as follows. My web service references this class and is used as the interface.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.ServiceModel;
    using System.Runtime.Serialization;
    [DataContract]
        [MetadataType(typeof(CustomerMetaData))]
        public partial class Customer
        {
        }
     
        public class CustomerMetaData
        {
            [DataMember]
            public object CustomerID { getset; }
     
            [Required]
            [StringLength(50)]
            [DataType(DataType.EmailAddress)]
            [DataMember]
            public object Email { getset; }
    

    When I hit the Submit button on the form, it tries to add the record and does not do any validation. A runtime error occurs informing me that the email address is required. I obvioulsy want this validation to be done up front with the data annotations.

    How can I accomplish this?


    Bill Yeager

    An actual runtime error is coming back saying
    that the email address should not be NULL when the record tries to be added. This
    is correct. The database column requires a value.

     

    I thought that by having the data annotations in the model, if there is
    something wrong with the front end and the model is not valid once the form
    tries to be posted, the corresponding data annotation error should display on
    the form. I was under the impression that there is no need for writing any
    specific client side validation. The model is supposed to take care of that for
    you. Am I incorrect in this assumption?

    Tuesday, August 23, 2011 7:24 PM

All replies

  • Hi Bill,

    Welcome!

    I think you can refer here: Validation with the Data Annotation Validators, Validation is new feature introduced in CTP5, so you need to upgrade to EF4.1 to use it. 

    You can refer this Blog and the other.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, August 24, 2011 11:46 AM
    Moderator
  • Alan, I've already viewed that article. It is not set up for the Database First method. It is set up for Code First.

    Additionally, the content in there is outdated as far as the DLLs go. Check the DLLs I'm using in the above post.

    The bottom line is this....

    My data model for the Email field specifies the following:

    [Required]
            [StringLength(50)]
            [DataType(DataType.EmailAddress)]
    The ModelState.Count parameter is correct and the keys are correct along with the values I'm checking during debugging in the collection. 
    It's just not setting the ModelState.IsValid property to FALSE based on the above directives.
    There seems to be no correlation between the Model and the directives above.
    How can this be resolved?

    Bill Yeager
    Wednesday, August 24, 2011 7:07 PM
  • Alan, I have more detail for you...

    As soon as the Submit button is pressed, I'm going to the method in my Controller that handles the post and checks for "If (ModelState.IsValid)" which is always true when it shouldn't be. I'm purposely making an error to see if the validation is caught.

    I've already viewed that article. It is not set up for the Database First method. It is set up for Code First. The way I have my Model class set up is supposed to be the way to set it up using EntityFramewowrk with the DataBase First methodology. Take a look at the previous post to see how the class is set up.

    Additionally, the content in there is outdated as far as the DLLs go. Check the DLLs I'm using in the above post.

    The bottom line is this....

    My data model for the Email field specifies the following:
    [Required]
            [StringLength(50)]
            [DataType(DataType.EmailAddress)]

    The ModelState.Count parameter is correct and the ModelState.Keys are correct along with their respective values that I am checking during debugging in the collection. It's not setting the ModelState.IsValid property to FALSE based on the above directives.

    The Model directives above are not being triggered on the front end for validation.

    It's amazing how Microsoft can't explain a simple methodology of how to use DataAnnotations using DataBase First.

    How can this be resolved? 


    Bill Yeager
    Wednesday, August 24, 2011 8:41 PM
  • Hi Bill,

    You can use Database-First and then use "ADO.net DbContext Generator" item to create your DbContext Class and Models. You can refer EF 4.1 Model & Database First Walkthrough, please go to Step 4---- "Swap to DbContext Code Generation". But you should install EF4.1, the item will be install automatically. It's easy to convert object context to dbcontext.

    By the way, I'm not familiar with ASP.NET MVC, thanks for understanding.

    Have a nice day.

     


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, August 25, 2011 12:03 PM
    Moderator
  • Alan, thanks for replying.

    I've downloaded the update to EF 4.1 at the following link (I already have EF 4.1 installed):

    http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=26825

     

    After doing Step 4 at the following link, I get a compile error when I try and build my project:

    http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-model-amp-database-first-walkthrough.aspx

     

    After a successfull install (from the first link above), I am still getting an error because the following DLL can't be found:

    System.Data.Entity.Infrastructure
    

    In addition, it is not in the "Add Reference" dialog box.

    How can I get this DLL installed?


    Bill Yeager
    Thursday, August 25, 2011 8:45 PM
  • Hi Bill,

    Thanks for your feedback.

    System.Data.Entity.Infrastructure namespace is defined in EntityFramework.dll.

    There isn't need to update to EF4.1 Update1, please make sure the EntityFramework.dll has been refered in your project.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, August 26, 2011 8:17 AM
    Moderator
  • Alan, in my project with the edmx file, there is no EntityFramework.dll in the reference list nor is it availalbe when searching for it when trying to add a reference.

    what to do????

     


    Bill Yeager
    Friday, August 26, 2011 2:51 PM
  • OK... I found it. I needed to install the EntityFramework package.
    Bill Yeager
    Saturday, August 27, 2011 12:33 AM
  • I did perform an "Add code generation item" with the ADO.NET DBContext nuget package. The classes were created fine.

    There are articles on the web how to do this with CodeFirst, but I have seen none on how to do this with DataBaseFirst. How can this be accomplished?

    Once again, my Customer class is as follows. using System;

    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.ServiceModel;
    using System.Runtime.Serialization;
     
    namespace YeagerTechModel
    {
        [Serializable]
        [DataContract]
        //[MetadataType(typeof(CustomerMetaData))]
        public partial class Customer
        {
            public Customer()
            {
                this.Projects = new HashSet<Project>();
            }
     
            [DataMember]
            public short CustomerID { get; set; }
     
            [Required]
            [StringLength(50)]
            [DataType(DataType.EmailAddress)]
            [DataMember]
            public string Email { get; set; }
     
            [StringLength(50)]
            [DataType(DataType.Text)]
            [DataMember]
            public string Company { get; set; }
     
            [StringLength(50)]
            [DataType(DataType.Text)]
            [DataMember]
            public string FirstName { get; set; }
     
            [StringLength(50)]
            [DataType(DataType.Text)]
            [DataMember]
            public string LastName { get; set; }
     
            [StringLength(50)]
            [DataType(DataType.Text)]
            [DataMember]
            public string Address1 { get; set; }
     
            [StringLength(50)]
            [DataType(DataType.Text)]
            [DataMember]
            public string Address2 { get; set; }
     
            [StringLength(50)]
            [DataType(DataType.Text)]
            [DataMember]
            public string City { get; set; }
     
            [StringLength(2)]
            [DataType(DataType.Text)]
            [DataMember]
            public string State { get; set; }
     
            [StringLength(10)]
            [DataType(DataType.Text)]
            [RegularExpression(@"^\d{5}(-\d{4})?$")]
            [DataMember]
            public string Zip { get; set; }
     
            [StringLength(12)]
            [DataType(DataType.PhoneNumber)]
            [DataMember]
            public string HomePhone { get; set; }
     
            [StringLength(12)]
            [DataType(DataType.PhoneNumber)]
            [DataMember]
            public string CellPhone { get; set; }
     
            [StringLength(100)]
            [DataType(DataType.Url)]
            [DataMember]
            public string Website { get; set; }
     
            [StringLength(50)]
            [DataType(DataType.EmailAddress)]
            [DataMember]
            public string IMAddress { get; set; }
     
            [DataMember]
            public System.DateTime CreatedDate { get; set; }
     
            [DataMember]
            public Nullable<System.DateTime> UpdatedDate { get; set; }
     
            public virtual ICollection<Project> Projects { get; set; }
        }
    }

    When I debug the "if (ModelState.IsValid)" in my client, the property always returns true. It's as if the DataAnnotations are not even being recognized. When debugging, I check the ModelState object and has all the property values there (an empty string in all cases since I'm trying to force an error). I should be getting an isRequired error on the email address which I'm purposely leaving blank.       

    [HttpPost]
            public ActionResult Create(YeagerTechWcfService.Customer cust)
            {
                if (ModelState.IsValid)
                {
                    try
                    {
                        db.AddCustomer(cust);
                        TempData["ErrCode"] = "Customer successfully added.";
                        return RedirectToAction("Index", "Home");
                    }
                    catch (Exception ex)
                    {
                        ViewData["ErrCode"] = "CustErr";
                        ViewBag.Error = ex.Message;
                        return View();
                    }
                }
                else
                    return View();
            }


    Bill Yeager
    Monday, September 5, 2011 11:31 PM