Retrieving [DisplayName] DataAnnotation in T4 template - asp.net-mvc

I have downloaded the MVCScaffolding nuget package within VS2010. I am trying to retrieve a [DisplayName data annotation from my model in order to use it within the index.cs.t4 template.
This page OneToMany Relationships has shown me how to modify the index template in order to provide a link which will take me to the controller index for my child objects. Which in this case from emails to emailrecipients. The problem is i have called my controllers emailcontroller and emailrecipientscontroller rather than their rather less descriptive tables names which i would prefer to hide anyway. i have equally decorated the metadataobject which the t4 template uses(tbl_My_unwieldytablename_emailMetadata) with this displayname (emailrecipients) dataannotation and i was hoping i could modify the template in order to replace the name for the relation to use the displayname which is my controller name i.e.
[MetadataType(typeof(tbl_My_unwieldytablename_emailMetadata))]
public partial class tbl_My_unwieldytablename_email
{
internal sealed class tbl_My_unwieldytablename_emailMetadata
{
[ScaffoldColumn(false)]
[Required(ErrorMessage="id is required")]
public Int32 id { get; set; }
[DataType(DataType.Date)]
public DateTime send_date { get; set; }
[StringLength(255)]
public String title { get; set; }
[DataType(DataType.MultilineText)]
public String message { get; set; }
[StringLength(50)]
public String author { get; set; }
[StringLength(80)]
[DataType(DataType.EmailAddress)]
public String author_email { get; set; }
[DataType(DataType.MultilineText)]
public String attachment { get; set; }
[DataType(DataType.Date)]
public DateTime created_date { get; set; }
public Int32 batches { get; set; }
[DataType(DataType.Date)]
public DateTime complete_date { get; set; }
[DisplayName("emailrecipients")]
public EntityCollection<tbl_My_unwieldytablename_email_recipients> tbl_My_unwieldytablename_email_recipients { get; set; }
}
Cheers
Tim

[Table("tbl_My_unwieldytablename_email")]
Public Class Email
[Table("tbl_My_unwieldytablename_email_recipients")]
Public Class EmailRecipients
Should map your classes to the database tables

Related

HowTo fetch data to viewmodel the quickest way

I have a simple problem with my site.
Inside my site, I'm using two different models, with some identical named fields.
Because of collision, I have to give them unique names and for not loosing the modelbinding, I decided to use viewModels.
So I have a Model like this:
namespace MySite.Models
{
public class Function : BaseEntity
{
//Beziehung zur Funktionsgruppe
[Required]
[Display(Name = "Übergeordnete Funktion")]
public int FunctionGroupId { get; set; }
public virtual FunctionGroup FunctionGroup { get; set; }
[Required]
[StringLength(200)]
[Display(Name = "Bezeichnung")]
public string Name { get; set; }
}
}
And I have a new ViewModel like this:
namespace MySite.ViewModels
{
public class FunctionViewModel
{
//Properties of BaseEntity
public int F_Id { get; set; }
[Display(Name = "Erstellt")]
public string F_Created { get; set; }
[Display(Name = "Bearbeitet")]
public string F_LastChange { get; set; }
[Display(Name = "Bearbeiter")]
public string F_ByUser { get; set; }
//Beziehung zur Funktionsgruppe
[Required]
[Display(Name = "Übergeordnete Funktion")]
public int F_FunctionGroupId { get; set; }
public virtual FunctionGroup F_FunctionGroup { get; set; }
[Required]
[StringLength(200)]
[Display(Name = "Bezeichnung")]
public string F_Name { get; set; }
}
}
Now my Question is, is there a way to automatically fetch the data of the corresponding model, while loading the ViewModel?
Something like a kind of function directly inside the { get; set; }?
Actually I load field by field form the model into the ViewModel.
Hope that I could have described Right, what I'd like to do.
Carsten
You can use Automapper for mapping or getting your data from Model to ViewModel or vice-versa. It will be hard for you to map/configure if your name of your property is different so have the same name in view model as well. (If possible)

Navigation property not showing in scaffold with code first model in EF5 MVC4

I have the following model for an article.
public class Article
{
[Key]
public int ArticleId { get; set; }
[Required(ErrorMessage = "Title is required."), MaxLength(80)]
public string Title { get; set; }
[Required(ErrorMessage = "Body is required.")]
public string Body { get; set; }
public DateTime Time { get; set; }
public int AuthorId { get; set; }
// Navigation properties
public virtual UserProfile Author { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
The UserProfile is an extendend version of the default in the MVC4 standard project.
Now, in my scaffolded controller/view, there is no way to enter the Author.
My database (MySQL) contains a field with named Author_UserId of type int.
What is wrong?
Also, is it really necessary for the author to be referenced both via the navigation property and the AuthorId
It's not common to use 2 the same Foreign keys of a specific table at any table. Such this interpreted as data redundancy. To solve the problem without any redundancy, i suggest bellow model to you:
public class Article
{
[Key]
public int ArticleId { get; set; }
[Required(ErrorMessage = "Title is required."), MaxLength(80)]
public string Title { get; set; }
[Required(ErrorMessage = "Body is required.")]
public string Body { get; set; }
public DateTime Time { get; set; }
public int AuthorId { get; set; }//determine name of foreign key here of type primary key of navigatable table
// Navigation properties
[ForeignKey("AuthorId")]
public virtual UserProfile Author { get; set; }//column with name 'AuthorId'
public virtual ICollection<Tag> Tags { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
Solution above, used to self naming navigation property foreign key.
I wish be useful.

MVC how to hide an ID field when creating VIEW using Scaffolding

I have a Class generated with POCO T4 Template, I'm using this code to adding to the Partial Class some DataAnnotation.
I would like to know:
How to hide the field OptionId (in the DB is a Primary Key with IDENTITY) so the User does not need input this value in the View (but with setting in the model).
Also I would like to know if [DatabaseGenerated(DatabaseGeneratedOption.Identity)] is REQUIRED or EF with POCO will create automatically the new ID (is IDENTITY)
namespace MyProject.Models
{
[MetadataType(typeof(ReOptionMetadata))]
public partial class ReOption
{
private class ReOptionMetadata
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[HiddenInput(DisplayValue = false)] // Is it correct?
public int OptionId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Value { get; set; }
[Required]
public string Description { get; set; }
[Required]
public string NoteInternal { get; set; }
}
}
}
#Html.HiddenFieldFor(model => model.ColumnWhichContainsTheId) ?

.NET MVC Render Views with custom data annotations

Playing around a little bit with a .NET MVC web application, and have questions about ViewModels and the data annotations.
Lets say I have a ViewModel:
public class MyViewModel
{
[DisplayName("First Name")]
public string FirstInfoName { get; set; }
[DisplayName("First Information")]
public string FirstInfo { get; set; }
[DisplayName("Second Name")]
public string SecondInfoName { get; set; }
[DisplayName("Second Information")]
public string SecondInfo { get; set; }
[DisplayName("Third Name")]
public string ThirdInfoName { get; set; }
[DisplayName("Third Information")]
public string ThirdInfo { get; set; }
}
When I want to create an Edit view my ViewModel I use:
#Html.EditorForModel()
This works great, MVC will render textboxes for me. But let's say that I want to render tabs in my view, So the properties of the ViewModel will be grouped depending on data annotations.
Example:
public class MyViewModel
{
[Tab(1)]
[DisplayName("First Name")]
public string FirstInfoName { get; set; }
[Tab(1)]
[DisplayName("First Information")]
public string FirstInfo { get; set; }
[Tab(2)]
[DisplayName("Second Name")]
public string SecondInfoName { get; set; }
[Tab(2)]
[DisplayName("Second Information")]
public string SecondInfo { get; set; }
[Tab(3)]
[DisplayName("Third Name")]
public string ThirdInfoName { get; set; }
[Tab(3)]
[DisplayName("Third Information")]
public string ThirdInfo { get; set; }
}
Is it possible to do something like this? Maybe using templates?
While i'm not going to say you can't do this, it is certainly not going to be an easy solution. The reason is attributes are evaluated on a per property basis. Tabs are typically displayed withing a group, and there's not a good way to alter your html to include groups based on multiple attributes of the same type.

EF Code First Foreign Key's

I am working with the EF Code First library trying to work on an appointment scheduling app.
The model's I have are going to be a Client, Appointment, and AppointmentType...
Basically each Client can have a set of Appointments, and each Appointment can have a single AppointmentType...
The code is as follows:
public class Client
{
[ScaffoldColumn(false)]
public int ClientID { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[EmailAddress]
[Required]
public string Email { get; set; }
[DataType("DateTime")]
public DateTime Birthday { get; set; }
[Required]
public string CellPhone { get; set; }
public string HomePhone { get; set; }
public string Notes { get; set; }
public virtual ICollection<Appointment> Appointments{ get; set; }
public string Name {
get{
return FirstName + " " + LastName;
}
}
public class Appointment
{
[ScaffoldColumn(false)]
public int AppointmentID { get; set; }
[ScaffoldColumn(false)]
public int ClientID { get; set; }
[ScaffoldColumn(false)]
public int AppointmentTypeID { get; set; }
[Required]
public DateTime AppointmentDate { get; set; }
public string Notes { get; set; }
public virtual AppointmentType AppointmentType { get; set; }
public virtual Client Client { get; set; }
}
public class AppointmentType
{
[ScaffoldColumn(false)]
public int AppointmentTypeID { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public virtual Appointment Appointment { get; set; }
}
Everything works well when I create an appointment type, and a client, but when I create an appointment I get the following error...
InnerException {"The INSERT statement conflicted with the FOREIGN KEY constraint \"Appointment_Client\". The conflict occurred in database \"Salon.Models.SalonContext\", table \"dbo.Clients\", column 'ClientID'.\r\nThe statement has been terminated."} System.Exception {System.Data.SqlClient.SqlException}
If more details are needed, please let me know...I am just trying to figure out if I am missing anything in the setup.
This is what happens when I debug on the post to create the Appointment...All the ID's are as 0 which is correct, but should the other fields not be null?? Or does it matter...Just not very familiar with how things should look this being my first EF Code First project...
According to your setup, one AppointmentType can only have one Appointment. This is a one-to-one mapping. In this case, you better move the AppointmentType into the Appointment entity. Otherwise, what I believe is more logical, an AppoitmentType can have many Appointments but one Appointment can have only one AppointmentType. Accordingly, you should have a virtual ICollection inside your AppointmentType entity.
public class AppointmentType
{
[ScaffoldColumn(false)]
public int AppointmentTypeID { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Appointment> Appointments { get; set; }
}
I am not sure this is what's causing the problem but it could be. Sometimes mapping faults cause some weird exceptions to be thrown. Give it a try and let me know if your problem gets resolved.
By your constraints AppointmentType and Client cannot be null in Appointment. You can delete constraints or set correct objects in object properties. For example create Client and AppointmentType and then create Appointment for created Client with created AppointmentType

Resources