Overriding default Required ErrorMessage property in .NET Core - entity-framework

I have generated my DbContext using EF with DataAnnotations set and would like to override the Required ErrorMessage property using ModelMetadataType
eg
Generated class
public partial class ControlType
{
public ControlType()
{
Rule = new HashSet<Rule>();
}
[Key]
public int ControlTypeId { get; set; }
[Required]
[StringLength(200)]
public string Name { get; set; }
[InverseProperty("ControlType")]
public virtual ICollection<Rule> Rule { get; set; }
}
My extension class
[ModelMetadataType(typeof(ControlTypeMeta))]
public partial class ControlType
{
}
public class ControlTypeMeta
{
[Display(Name = "Id")]
public int ControlTypeId { get; set; }
[Display(Name = "Control type")]
[Required(ErrorMessage = "'{0}' is required")]
public string Name { get; set; }
}
With the above I am expecting the Required ErrorMessage to be output as "'Control type' is required", but instead I get the default "The Control type field is required"
Does anyone know how I can override the message (without creating view models)

Related

Using Inherited Entity Class in asp.net EF Core

I have following Entity Class (Which mapped directly to table of SQL Server DB)
public class PROCESSCARD : BaseClass
{
[Key]
[Display(Name = "Card No")]
public String ProcessCardID { get; set; }
[Display(Name = "Entry Date")]
public DateTime EntryDate { get; set; }
[Display(Name ="Job Type")]
public String JobType { get; set; }
[Display(Name = "Job / Non Job")]
public String JobNonJob { get; set; }
[Display (Name = "Cost Booking")]
public String CostBooking { get; set; }
[Display(Name = "Planned Hrs/Qty")]
public Decimal? PlannedHours { get; set; }
}
Above class inherits from BaseClass which is as follow
public class BaseClass
{
[NotMapped]
public String StatusMessage { get; set; }
}
Now upto this there is no issue everything is just fine,
but I am storing deleted data of entity PROCESSCARD to PROCESSCARD_HIST, and I want to show deleted history data to user.
Structures of both entity (PROCESSCARD and PROCESSCARD_HIST are ditto same) so I created another entity class PROCESSCARD_HIST, and to avoid duplicate members, I inherited PROCESSCARD_HIST from PROCESSCARD,
public class PROCESS_CARD_HIST : PROCESS_CARD
{
}
but now when I try to access data from PROCESSCARD_HIST class, it throws error like "Invalid column name 'Discriminator'",
Any Idea how I can achieve this?
If you don't want to repeat the properties in both classes, introduce another unmapped superclass
public class ProcessCardBase : BaseClass
{
[Key]
[Display(Name = "Card No")]
public String ProcessCardID { get; set; }
[Display(Name = "Entry Date")]
public DateTime EntryDate { get; set; }
[Display(Name ="Job Type")]
public String JobType { get; set; }
[Display(Name = "Job / Non Job")]
public String JobNonJob { get; set; }
[Display (Name = "Cost Booking")]
public String CostBooking { get; set; }
[Display(Name = "Planned Hrs/Qty")]
public Decimal? PlannedHours { get; set; }
}
Then
public class ProcessCard : ProcessCardBase
{
}
public class ProcessCardHistory : ProcessCardBase
{
}

.Include() method in APIController with one-to-many relations?

One display should have many media(images, videos) in my project. I'm using Entity Framework Core to build my database, and CRUD with my API Controller.
I designed my Model classes as such:
[Table("Displays")]
public class Display : ConcurrencyCheck
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "{0} skal udfyldes!")]
[Display(Name = "Display navn")]
public string Name { get; set; }
[Display(Name = "Display tændt")]
public bool IsOn { get; set; }
[Display(Name = "Display beskrivelse")]
public string Description { get; set; }
public IEnumerable<Video> Videos { get; set; }
public IEnumerable<Image> Images { get; set; }
}
public abstract class Media : ConcurrencyCheck
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "{0} skal udfyldes!")]
[Display(Name = "Medie navn")]
public string Name { get; set; }
[Display(Name = "Medie beskrivelse")]
public string Description { get; set; }
[Display(Name = "Medie filtype")]
public string FileType { get; set; }
[Required(ErrorMessage = "{0} skal udfyldes!")]
[Display(Name = "Medie filsti")]
public string FilePath { get; set; }
public int? DisplayId { get; set; }
[ForeignKey("DisplayId")]
public Display Display { get; set; }
}
[Table("Videos")]
public class Video : Media
{
[Display(Name = "Frames")]
public int Frames { get; set; }
[Display(Name = "Filsti på undetekster")]
public string SubtitlesPath { get; set; }
[Display(Name = "Filsti på thumbnail")]
public string ThumbnailPath { get; set; }
}
[Table("Images")]
public class Image : Media
{
}
public abstract class ConcurrencyCheck
{
[Timestamp]
public byte[] RowVersion { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy HH:mm}", ApplyFormatInEditMode = true)]
public DateTime CreatedDate { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy HH:mm}", ApplyFormatInEditMode = true)]
public DateTime? UpdatedDate { get; set; }
}
And my API controllers are scaffolded with 'API Controller with actions, using Entity Framework'.
Currently in the api-controller 'DisplaysController', I don't see the .Include(x => x.Media), though I read somewhere it's used? One display should have many media(images, videos).
Should I include it somehow somewhere, or does it do that automatically by the models I have?
scaffolded with API Controller with actions, using Entity Framework just provide the most basic five database operation methods -- select , select by id, update, add and delete. Its purpose is to help users build basic crud faster and more easily. You can add your own code on the default code template.
The default code template
Add your own code

Why does PersistentObjectSpace sometimes return a proxy and sometimes return an object?

The debugger shows me that in the following code
_taxRate =
PersistentObjectSpace.FindObject<TaxRate>(CriteriaOperator.Parse("[TaxCodeId] = ?", TaxCodeId));
var _product2 =
PersistentObjectSpace.FindObject<Product>(CriteriaOperator.Parse("[ItemId] = ?", ItemId));
_taxRate is a poco but _product2 is a proxy
The objects are
[Table("TaxCode")]
[DefaultProperty("TaxCode")]
[ImageName("BO_List")]
public class TaxRate : BasicBo
{
[Key] public short TaxCodeId { get; set; }
[Required]
[RuleRequiredField(DefaultContexts.Save)]
[StringLength(20, ErrorMessage = "The field cannot exceed 20 characters. ")]
public string TaxCode { get; set; }
[Required]
[RuleRequiredField(DefaultContexts.Save)]
public decimal Percentage { get; set; }
public override string ToString()
{
return TaxCode;
}
}
and
[Table("MyExtItem")]
[DefaultProperty("ProductCode")]
[NavigationItem("Config")]
public class Product : BasicBo
{
[Key]
public int ItemId { get; set; }
public string ItemName { get; set; }
[Column("Item Number")] public string ProductCode { get; set; }
[MaxLength(10)] public string UnitName { get; set; }
public int? ProductImageId { get; set; }
[ForeignKey("ProductImageId")] public virtual ProductImage ProductImage { get; set; }
[ForeignKey("ItemId")] public virtual ExtMaterialProperty ExtMaterial { get; set; }
}
This is expected behaviour when EF is configured to support lazy loading.
TaxRate holds no references to other entities so EF can return a concrete instance.
Product contains two references to other entities, ProductImage and ExtMaterial.
If I run the code:
var product = context.Products.Single(x => x.ItemId == itemId);
to get a product, EF uses a proxy in order to be prepared for when I try to access something like ProductImage.
var imageName = product.ProductImage.Name;
You can disable the proxies using Configuration.ProxyCreationEnabled on the DbContext. (EF6) This does mean that any references will need to be eager loaded or explicitly loaded, as Lazy Loading will not function without the proxies.

The entity type 'Program' requires a primary key to be defined

I am trying to make a simple website that tracks students, programs, and classes. I've created the entities and I'm getting an error when trying to add the migration.
"The entity type 'Program' requires a primary key to be defined."
I have tried using the [Key] attribute and there is an Id field. The other table was created just fine. What else should I try?
Here is the problem class:
public class Program
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool UseRanks { get; set; }
}
Here is another table that I had no problems creating a migration for:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string CellPhone { get; set; }
public string HomePhone { get; set; }
public string WorkPhone { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public DateTime BirthDate { get; set; }
}
Here is what is in my ApplicationDbContext class:
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
//public DbSet<Attendance> Attendances { get; set; }
public DbSet<Person> People { get; set; }
public DbSet<Bill> Bills { get; set; }
//public DbSet<Session> Sessions { get; set; }
public DbSet<Program> Programs { get; set; }
}
I've commented out the other entities because I was trying to add them one at a time. Trying to add a migration with all the entities resulted in the same error with the same specific class.
Complete shot in the dark, but based on the name of this class, I'm guessing you're referencing the wrong Program. Make sure that your DbSet<Program> is actually using your Program entity and not something like the Program class used at the console app level. You'll likely need to explicitly use the namespace, i.e. DbSet<MyApp.Models.Program>.
You might also consider changing the name of the class to remove any chance of ambiguity. There's some class names that are just going to wreck havoc trying to use them because they'll conflict with framework stuff constantly. It's usually more hassle than it's worth just to have that particular name. Program is one of those.
You can try to use this way:
public class Program
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool UseRanks { get; set; }
}
Adding [Key] attribute to the Id property.
In the file ApplicationDbContext.cs, you can override OnModelCreating method:
public DbSet<Program> Programs { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Program>().ToTable("Programs").HasKey(x => x.Id);
}

how to update .edmx file without effecting all the other model classes?

how to update .edmx file without effecting all the other model classes?
when I update the edmx file it recreates all the other classes and this is a problem for me because I made some changes on the other classes so how can I modify it without affecting the other classes.
For example this is one of my classes
public partial class company
{
public company()
{
this.Departments = new HashSet<department>();
this.CustomersOfTheCompany = new HashSet<company_customers>();
this.CompaniesTheCompanyCustomerFor = new HashSet<company_customers>();
this.CustomerProjectDetails = new HashSet<cus_pro_connector>();
this.CompanyAsSupplier = new HashSet<company_suppliers>();
this.CompanyAsCustomer = new HashSet<company_suppliers>();
this.Tickets = new HashSet<oneTimeAuthenticationTicket>();
}
[Required(ErrorMessage = "Company name is required")]
[StringLength(200, MinimumLength = 3, ErrorMessage = "Length Of The Company Name Should Be More Than Three Letters")]
public string CompanyName { get; set; }
[Required]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string Email { get; set; }
[Required]
public int Country { get; set; }
public int company_id { get; set; }
public string Logo { get; set; }
public string Description { get; set; }
private CompanyDTO _CDTO = new CompanyDTO();
public CompanyDTO CDTO { get { return this._CDTO; } set { this._CDTO = value; } }
public virtual ICollection<department> Departments { get; set; }
public virtual country CountryOfTheCompany { get; set; }
public virtual ICollection<company_customers> CustomersOfTheCompany { get; set; }
public virtual ICollection<company_customers> CompaniesTheCompanyCustomerFor { get; set; }
public virtual ICollection<cus_pro_connector> CustomerProjectDetails { get; set; }
public virtual ICollection<company_suppliers> CompanyAsSupplier { get; set; }
public virtual ICollection<company_suppliers> CompanyAsCustomer { get; set; }
public virtual ICollection<oneTimeAuthenticationTicket> Tickets { get; set; }
}
so when I modify the .edmx the class attributes will no longer be available.
It is not possible to retain edits to generated files when you re-generate them. If you need to apply attributes to generated code, there is a MetadataType mechanism that allows you to specify validation attributes in another partial class.
See this other answer or MSDN for further information on this.
I don't understand your example - But I will explain here:
Let's say you have the following Entity Models:
And the User.cs looks like this:
public partial class User
{
public User()
{
this.UserWindows = new HashSet<UserWindow>();
}
public int UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public virtual ICollection<UserWindow> UserWindows { get; set; }
}
Add a new file and call it Extensions.cs, then create a New Partial Class in this File:
Then you can Add Properties to this Class:
public partial class User
{
public int NewUserId { get; set; }
}
And whenever you create a New User Object you will see your new Properties:
Similarly you can do this for UserWindow.cs
Extensions.cs:
public partial class User
{
public int NewUserId { get; set; }
}
// Similarly you can do
public partial class UserWindow
{
public string MyNewProperty { get; set; }
}
Then