Solved

MVC4 and Entity Framework

Posted on 2014-01-24
4
566 Views
Last Modified: 2014-01-24
I am learning MVC4 and Entity Framework and am trying to build a very simple project to maintain a simple file.  I used scaffolding when creating my Controllers and Views so I am able to Create a new record and View existing records very easily.  Now I am trying to add validation to my create screen and am having difficulty.

I found an article on the Web that allows me to specify properties so the size and maxlength of a textbox can be specified which is working for me.  I also added a Required attribute to my field which again worked for me.

Now here is my problem.  I did all the attributes in the Class that was generated automatically which states that Manual changes to the file will be overwritten if hte code is regenerated.

My solution was to try and extend the class to redefine those fields that I need to put special attributes on but I am not doing it correctly.

Here is how the database is constructed:
ENL_GroupName is a table that has the following fields:
Int ENLGroupNameID (PK, not null)
String ENLGroupName (max 30 chars, not null)
Bit IsActive (1 or 0, not null)

ENL_MultiGroup_Contacts is a table that has a reference to the ENLGroupNameID in the ENL_GroupName table and has the following fields:
Int MultiGroupContactID (PK, not null)
String FirstName (max 50 chars, not null)
String LastName (max 50 chars, not null)
Int EmployeeProfileID
String PhoneNumber (max 12 chars, not null)
Int PhoneNumberType (not null)
String EmailAddress (max 150 chars)
Int ENLGroupNameID (FK, not null)
Bit IsActive (1 or 0, not null)


Here is what I have so far:

ENL_GroupName.cs is the class generated automatically when I created my model.  
//------------------------------------------------------------------------------
// <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>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace ENL.Models
{
    public partial class ENL_GroupName
    {
        public ENL_GroupName()
        {
            this.ENL_MultiGroup_Contacts = new HashSet<ENL_MultiGroup_Contacts>();
        }
    
        public int ENLGroupNameID { get; set; }
        [HtmlProperties(Size = 30, MaxLength = 30)]
        [Required(ErrorMessage = "* Group Name is required")]
        public string ENLGroupName { get; set; }
        public bool IsActive { get; set; }
    
        public virtual ICollection<ENL_MultiGroup_Contacts> ENL_MultiGroup_Contacts { get; set; }
    }
    
}

Open in new window


GroupNameExtended.cs is my attempt to override the ENLGroupName in the ENL_GroupName.cs class (I've never done an override before so that may be where my problem is)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace ENL.Models
{
    public partial class ENL_GroupName
    {
        [HtmlProperties(Size = 30, MaxLength = 30)]
        [Required(ErrorMessage = "* Group Name is required")]
        public string ENLGroupName { get; set; }
    }
}

Open in new window


When I compile I get the following error in GroupNameExtended.cs:
Error      4      The type 'ENL.Models.ENL_GroupName' already contains a definition for 'ENLGroupName'      C:\Visual-Studio-Projects\ENL\ENL\Models\GroupNameExtended.cs      13      23      ENL

Can someone point me in the right direction for adding the attributes to my field without changing the code in the generated ENL_GroupName.cs class?  

All help is greatly appreciated!!
0
Comment
Question by:dyarosh
  • 2
  • 2
4 Comments
 
LVL 21

Accepted Solution

by:
Craig Wagner earned 500 total points
ID: 39807404
The solution to your problem is to create a metadata class and use the MetadataType attribute to point to it. Here's an article with code examples on how to do that.

http://stackoverflow.com/questions/14059455/adding-validation-attributes-with-an-entity-framework-data-model
0
 

Author Comment

by:dyarosh
ID: 39807464
I followed the example in your link but it is not working.  Here is my new ENL_GroupNamesMetadata.cs class:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
internal sealed class ENL_GroupNamesMetadata
{
    [ENL.HtmlProperties(Size = 10)]
    public int ENLGroupNameID;
    [ENL.HtmlProperties(Size = 30, MaxLength = 30)]
    [Required(ErrorMessage = "* Group Name is required")]
    public string ENLGroupName;
}

Open in new window


I saved this in my Models folder.  

I don't receive any compile errors but when I run it and click Create on the Create screen without entering a GroupName, I get a DbEntityValidationException was unhandled by user code error.  This occurs because it is trying to save the record to the database without a groupname and groupname cannot be null.
0
 
LVL 21

Assisted Solution

by:Craig Wagner
Craig Wagner earned 500 total points
ID: 39807573
Did you do the other half where you put the MetadataType attribute on the original class?

[MetadataType( typeof( ENL_GroupNamesMetadata ) )]

Open in new window


BTW, the original article linked to seems to imply changing the generated class file, which is a bad idea because next time it gets regenerated you lose the MetadataType attribute. Because the generated class is a partial you can create a new file (e.g. ENL_GroupNamePartial.cs) and put the MetadataType attribute on it, i.e.

ENL_GroupNamePartial.cs

namespace ENL.Models
{
    [MetadataType( typeof( ENL_GroupNamesMetadata ) )]
    public partial class ENL_GroupName { }
}

Open in new window

0
 

Author Closing Comment

by:dyarosh
ID: 39807715
Thank you.  That did the trick for me.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

IntroductionWhile developing web applications, a single page might contain many regions and each region might contain many number of controls with the capability to perform  postback. Many times you might need to perform some action on an ASP.NET po…
Problem Hi all,    While many today have fast Internet connection, there are many still who do not, or are connecting through devices with a slower connect, so light web pages and fast load times are still popular.    If your ASP.NET page …
This video discusses moving either the default database or any database to a new volume.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now