I'm just starting out with MVC after developing using webforms for amny years. I'm working on an internal CRM type application as both a learning process and business requirement and would like to try and use the best approach possible to make it scalable
(splitting code between projects) and efficient.
One area I'm struggling with at this stage stems from following a code first tutorial and reading some books. For example I want to have the following record:
ContactID
Title
Forename
Surname
CreatedDate
ModifiedDate
That last two fields will be updated as changed occur and should not be shown in views. I created a basic class and then used per the tutorial used this to create the entity connection.
public class Contact
{
public int ContactID { get; set; }
public string Title { get; set; }
[Required(ErrorMessage = "Forename is required.")]
[MaxLength(50, ErrorMessage = "Forename cannot be longer than 50 characters.")]
public virtual string Forename { get; set; }
[Required(ErrorMessage = "Surname is required.")]
[MaxLength(50, ErrorMessage = "Surname cannot be longer than 50 characters.")]
public string Surname { get; set; }
// Need record here to link to user as created by
[HiddenInput(DisplayValue = false)]
public DateTime CreatedDate { get; set; }
[HiddenInput(DisplayValue = false)]
public DateTime ModifiedDate { get; set; }
}
public class TestDB : DbContext
{
public DbSet<Contact> Contacts { get; set; }
}
On the autogenerated views though fields were created for these date fields and they are not needed as I intend to update the automatically in code. As I wanted the fields to be required the page would not allow me to submit a new record without populating
the fields. I found I could hide them but it seems a bit unclean to include them in the page at all (although in one view I may want to display the data to an administrator) Would this be a situation where I need a seperate viewmodel class not including these
fields so they are not required, but then somehow pass this model + extra fields for the dates generated in code to the entity models?
Basically as I ramble on I realise I'm after a tutorial or example where these sorts of audit fields need to be in the db and entity model but not in all views. Would best practice be just to leave them as hidden fields? My concern is later I'll have a modifiedby
field as well as for normal users they should not neccesarily be able to view this type of info by viewing the page source. As it stands leaving the fields hidden doesn't protect the data from being output in the HTML
Thanks for answering, however that is not my issue. The code I showed was only the class to avoid confusion and annotations are working. My query is more on architecture to have a class model for code first that allowed me to programitically set created/modified
dates on fields in my table without them being exposed on the view (even in hidden form). I've been able to get them hidden but if I take away the fields entirly the model is not valid and won't post back, even if I try to force the values for the missing
fields in code.
public class Contact
{
[Required]
public string Forename { get; set; }
[ScaffoldColumn(false)]
public DateTime CreatedDate { get; set; }
[ScaffoldColumn(false)]
public DateTime ModifiedDate { get; set; }
public Contact()
{
CreatedDate = DateTime.Now;
}
}
public class Contact
{
[Required]
public string Forename { get; set; }
[ScaffoldColumn(false)]
public DateTime CreatedDate { get; set; }
[ScaffoldColumn(false)]
public DateTime ModifiedDate { get; set; }
public Contact()
{
CreatedDate = DateTime.Now;
}
}
public class TestDB : DbContext
{
public DbSet<Contact> Contacts { get; set; }
public override int SaveChanges()
{
foreach (var contact in ChangeTracker.Entries<Contact>().Where(e => e.State == System.Data.EntityState.Modified))
{
contact.Entity.ModifiedDate = DateTime.Now;
}
return base.SaveChanges();
}
}
private TestDB db = new TestDB();
public ActionResult Edit(int id)
{
var contact = db.Contacts.Find(id);
UpdateModel(contact);
db.SaveChanges();
return View();
}
Your constructor for Contact can set the CreatedDate. You can use the change tracking of DbContext to update modified entries prior to SaveChanges(). Plus using UpdateModel against the entity ensures you do not have to pass the datetime properties back and
forth between the server and client, they are marked with ScaffoldColumn false.
Basically as I ramble on I realise I'm after a tutorial or example where these sorts of audit fields need to be in the db and entity model but not in all views. Would best practice be just to leave them as hidden fields? My concern is later I'll have a modifiedby
field as well as for normal users they should not neccesarily be able to view this type of info by viewing the page source. As it stands leaving the fields hidden doesn't protect the data from being output in the HTML
nevets2001uk...
Member
67 Points
74 Posts
Starting with MVC Code First - Application Data Fields
Feb 20, 2012 04:20 PM|LINK
I'm just starting out with MVC after developing using webforms for amny years. I'm working on an internal CRM type application as both a learning process and business requirement and would like to try and use the best approach possible to make it scalable (splitting code between projects) and efficient.
One area I'm struggling with at this stage stems from following a code first tutorial and reading some books. For example I want to have the following record:
That last two fields will be updated as changed occur and should not be shown in views. I created a basic class and then used per the tutorial used this to create the entity connection.
public class Contact { public int ContactID { get; set; } public string Title { get; set; } [Required(ErrorMessage = "Forename is required.")] [MaxLength(50, ErrorMessage = "Forename cannot be longer than 50 characters.")] public virtual string Forename { get; set; } [Required(ErrorMessage = "Surname is required.")] [MaxLength(50, ErrorMessage = "Surname cannot be longer than 50 characters.")] public string Surname { get; set; } // Need record here to link to user as created by [HiddenInput(DisplayValue = false)] public DateTime CreatedDate { get; set; } [HiddenInput(DisplayValue = false)] public DateTime ModifiedDate { get; set; } }public class TestDB : DbContext { public DbSet<Contact> Contacts { get; set; } }On the autogenerated views though fields were created for these date fields and they are not needed as I intend to update the automatically in code. As I wanted the fields to be required the page would not allow me to submit a new record without populating the fields. I found I could hide them but it seems a bit unclean to include them in the page at all (although in one view I may want to display the data to an administrator) Would this be a situation where I need a seperate viewmodel class not including these fields so they are not required, but then somehow pass this model + extra fields for the dates generated in code to the entity models?
Basically as I ramble on I realise I'm after a tutorial or example where these sorts of audit fields need to be in the db and entity model but not in all views. Would best practice be just to leave them as hidden fields? My concern is later I'll have a modifiedby field as well as for normal users they should not neccesarily be able to view this type of info by viewing the page source. As it stands leaving the fields hidden doesn't protect the data from being output in the HTML
Steve
eric2820
Contributor
2777 Points
1161 Posts
Re: Starting with MVC Code First - Application Data Fields
Feb 20, 2012 06:14 PM|LINK
You need a using statement for System.ComponentModel.DataAnnotations
I would suggest going to www.msdn.com and looking up System.ComponentModel.DataAnnotations there.
http://www.my-msi.net/Admin
blog
If a post helps you, please mark it as Ansered, thank-you.
nevets2001uk...
Member
67 Points
74 Posts
Re: Starting with MVC Code First - Application Data Fields
Feb 21, 2012 02:58 PM|LINK
Thanks for answering, however that is not my issue. The code I showed was only the class to avoid confusion and annotations are working. My query is more on architecture to have a class model for code first that allowed me to programitically set created/modified dates on fields in my table without them being exposed on the view (even in hidden form). I've been able to get them hidden but if I take away the fields entirly the model is not valid and won't post back, even if I try to force the values for the missing fields in code.
Steve
eric2820
Contributor
2777 Points
1161 Posts
Re: Starting with MVC Code First - Application Data Fields
Feb 21, 2012 03:09 PM|LINK
Basically, you answered your own question when you suggested creating separate views for users and administrators to use. That is what I do at least.
http://www.my-msi.net/Admin
blog
If a post helps you, please mark it as Ansered, thank-you.
AndyBUK
Member
28 Points
7 Posts
Re: Starting with MVC Code First - Application Data Fields
Feb 21, 2012 03:14 PM|LINK
public class Contact { [Required] public string Forename { get; set; } [ScaffoldColumn(false)] public DateTime CreatedDate { get; set; } [ScaffoldColumn(false)] public DateTime ModifiedDate { get; set; } public Contact() { CreatedDate = DateTime.Now; } } public class Contact { [Required] public string Forename { get; set; } [ScaffoldColumn(false)] public DateTime CreatedDate { get; set; } [ScaffoldColumn(false)] public DateTime ModifiedDate { get; set; } public Contact() { CreatedDate = DateTime.Now; } } public class TestDB : DbContext { public DbSet<Contact> Contacts { get; set; } public override int SaveChanges() { foreach (var contact in ChangeTracker.Entries<Contact>().Where(e => e.State == System.Data.EntityState.Modified)) { contact.Entity.ModifiedDate = DateTime.Now; } return base.SaveChanges(); } } private TestDB db = new TestDB(); public ActionResult Edit(int id) { var contact = db.Contacts.Find(id); UpdateModel(contact); db.SaveChanges(); return View(); }Your constructor for Contact can set the CreatedDate. You can use the change tracking of DbContext to update modified entries prior to SaveChanges(). Plus using UpdateModel against the entity ensures you do not have to pass the datetime properties back and forth between the server and client, they are marked with ScaffoldColumn false.
ricka6
All-Star
15070 Points
2272 Posts
Microsoft
Moderator
Re: Starting with MVC Code First - Application Data Fields
Feb 21, 2012 06:26 PM|LINK
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application