Why referenced class validation attribute is not active? - c#

I have the following two object Classes :
[Serializable]
[DataContract]
public class W_ListItemPrice
{
[DataMember]
[Required]
public string nSize { get; set; }
[DataMember]
[Required, Range(0.5, Constants.FOOD_ITEM_MAX_SELLING_PRICE, ErrorMessage = "Price range invalid")]
public decimal ItemPrice { get; set; }
}
[Serializable]
[DataContract]
public class W_Listing
{
[DataMember]
[Required, RegularExpression(GlobalFromat.IDformat, ErrorMessage = "Invalid FoodID format")]
public Int64 MemberID { get; set; }
[DataMember]
[Required, RegularExpression(GlobalFromat.IDformat, ErrorMessage = "Invalid ScheduleID format")]
public Int64 ScheduleID { get; set; }
[DataMember]
[Required]
public List<Days?> FoodDays { get; set; }
[Required]
public List<W_ListItemPrice> ListingPortionPrice { get; set; }
public W_Listing()
{
oDays = new List<Days?>();
ListingPrice = new List<W_ListItemPrice>();
}
}
When I call the function with Class W_Listing, it validates only the member items listed in W_Listing class. It does not validate members in W_ListItemPrice class ? It does not care what I pass or not.
Why ?

Related

C# Overriding inherited validation

I have the following class that all of my entities inherit from:
using System.ComponentModel.DataAnnotations;
#nullable enable
namespace AutomationNavigator.Model.Core
{
public abstract class NamedEntity : Entity, INamedEntity
{
public NamedEntity() : base()
{
}
[MaxLength(100,ErrorMessage ="Name must be 100 characters or less.")]
[Required]
[MinLength(3, ErrorMessage = "Name must be at least 3 characters.")]
[RegularExpression("^[A-Za-z0-9_. ]{3,100}$")] // Alphanumeric with Underscore and Dot only
[Display(Name= "Name")]
public string? Name { get; set; }
}
}
The validation on the Name field is ok to universally apply except in a specific scenario that I just created where I need to allow special characters is name field in my app. Can I somewhow override/remove the Regex validation? The class I am trying to accomplish this for is:
namespace AutomationNavigator.Model.ProcessAssessment
{
public class ProcessFile: NamedEntity
{
[Display(Name = "OrganizationId")]
public Guid? OrganizationId { get; set; }
[ForeignKey("OrganizationId")]
[Display(Name = "Organization")]
public Organization? Organization { get; set; }
[Display(Name = "BusinessProcessId")]
public Guid? BusinessProcessId { get; set; }
[ForeignKey("BusinessProcessId")]
[Display(Name = "BusinessProcess")]
public BusinessProcess? BusinessProcess { get; set; }
[Display(Name = "ProcessDocumentId")]
public Guid? ProcessDocumentId { get; set; }
[ForeignKey("ProcessDocumentId")]
[Display(Name = "ProcessDocument")]
public ProcessDocument? ProcessDocument { get; set; }
[Display(Name = "ProcessFileStatusLookupId")]
public Guid? ProcessFileStatusLookupId { get; set; }
[ForeignKey("ProcessFileStatusLookupId")]
[Display(Name = "LookupValue")]
public LookupValue? LookupValue { get; set; }
[Display(Name = "BlobId")]
public Guid? BlobId { get; set; }
[ForeignKey("BlobId")]
[Display(Name = "Blob")]
public Blob? Blob { get; set; }
[Display(Name = "SizeInBytes")]
public double? SizeInBytes { get; set; }
[Display(Name = "Version")]
public double? Version { get; set; }
[MaxLength(500, ErrorMessage = "Description must be 500 characters or less.")]
[Display(Name = "Description")]
public string? Description { get; set; }
}
}
Virtual properties are a good way of allowing descendents to customise behaviour.
I would make the Name property virtual in the abstract class and override it in the derived specific class where you need to change the validation.
In the abstract class:
[MaxLength(100,ErrorMessage ="Name must be 100 characters or less.")]
[Required]
[MinLength(3, ErrorMessage = "Name must be at least 3 characters.")]
[RegularExpression("^[A-Za-z0-9_. ]{3,100}$")]
[Display(Name= "Name")]
public virtual string? Name { get; set; }
In the derived class:
public class ProcessFile: NamedEntity
{
public override string? Name { get; set;}
}
You can also make the base class' name directly available for the derived class and validate it. Something like:
public abstract class NamedEntity
{
protected string name;
public virtual string Name
{
get { return name; }
set
{
//validation, if any
}
}
public NamedEntity()
{
name = "";
}
}
public class ProcessFile: NamedEntity
{
public override string Name
{
get { return base.Name; }
set { base.Name = // new validation; }
}
public ProcessFile()
: base()
{
base.Name = "";
}
}
I hope it helps.
Cheers.

hi i am having an issue to update related data

I am trying to add a member to a group in my application, I need be able to add one or more members to a group. Please can you assist?
below are my classes
public class member
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int memberid { get; set;}
[Required]
[Display(Name ="first name")]
public string membername { get; set; }
[Required]
[Display(Name = "last name")]
public string memberlastname { get; set;}
[Required]
[Display(Name = "email address")]
[DataType(DataType.EmailAddress)]
public string email { get; set; }
public int groupid { get; set; }
public virtual group groups { get; set; }
}
and
public class group
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int groupid { get; set; }
[Required]
[Display(Name = "group name")]
public string groupname { get; set; }
public IEnumerable<member> members { get; set; }
}
One way would be to change the data type of your group.members property from an IEnumerable<member> to a List<member>:
public class group
{
// Other properties not shown
public List members { get; set; }
}
Then you could just call the Add method:
static void Main()
{
group g = new group();
member m = new member();
g.members.Add(m);

how to determine that my model pass all data annotations rule check or not?

I have scenario where I want to know is my model is valid or not.
here is my model
public class CallPartyModel
{
public System.Guid PartyId { get; set; }
public System.Guid FwCallMasterId { get; set; }
[Required(ErrorMessage = "Principal Party is required.")]
[Display(Name = "Principal Party")]
public System.Guid PrincipalPartyId { get; set; }
[Required(ErrorMessage = "Responsible Party is required.")]
[Display(Name = "Responsible Party")]
public System.Guid ResponsiblePartyId { get; set; }
[Display(Name = "File Type")]
public System.Guid FileTypeId { get; set; }
[Display(Name = "Agent Type")]
public Nullable<System.Guid> AgentTypeId { get; set; }
public string AgentTypeCode { get; set; }
public bool AdvancedRequired { get; set; }
public bool SeperateDARequired { get; set; }
public string PrincipalPartyName { get; set; }
public string ResponsiblePartyName { get; set; }
public string PrincipalReferenceCode { get; set; }
public string ResponsibleReferenceCode { get; set; }
public string FileTypeName { get; set; }
public string FileTypeCode { get; set; }
public string AgentTypeName { get; set; }
public bool? DAIssuedFlag { get; set; }
[Range(0, 999999999.999, ErrorMessage = "Value lies outside the 0 to 999999999.999 range")]
public decimal? AdvanceReceivedAmount { get; set; }
public System.Guid CreatedBy { get; set; }
public System.DateTime CreatedDateTime { get; set; }
public Nullable<System.Guid> ModifiedBy { get; set; }
public Nullable<System.DateTime> ModifiedDateTime { get; set; }
public bool IsDeleted { get; set; }
public Nullable<System.Guid> DeletedBy { get; set; }
public Nullable<System.DateTime> DeletedDateTime { get; set; }
//public virtual UserModel FwCore_Users { get; set; } //Created By User
//public virtual UserModel FwCore_Users1 { get; set; }//Modified By User
//public virtual UserModel FwCore_Users2 { get; set; }// Deleted by User
public bool IsDirtyCheck { get; set; }
public bool LockPrinFlag { get; set; }
public string LockPrinMsg { get; set; }
}
I have defined some rules for this ex. public decimal? AdvanceReceivedAmount { get; set; }
the range rule.
I know how to check model state when our model is bonded to view as ModelState.Isvalid()
but in my code I am working with tow diffident models, its in some wcf service, where I am getting the input as string for all properties and I can't define the data annotation rule on second model. So I have to transfer the data manually from model one to model two and in model two (CallPartyModel) I have define the data annotation rules. Now before performing any transaction in database, I have to check if the model properties's value are valid or not, I know I can do it manually but is there any method as modelState.IsValid() for this kind of scenario?
as:
CallPartyModel obj=new CallPartyModel();
obj.AdvanceReceivedAmount=88.88;
if(obj.IsValid())
{
//go
}
else
{
//Show the error according to property
}
Any suggestion or help will be appreciated
How about you check your model1 against model2 by loading the model2 with the values of Model1 and then using
Model2 m2 = new Model2();
//... load up the values into m2 from Model1
if(TryUpdateModel(m2)) //if it is ok (checks validation)
{
... your code...
}
I hope this helps.

Cannot convert anonymous type into my MVC model

When running a LINQ query, it runs fine and gets the expected results when I include the "result.Dump()" method. The anonymous types work fine.
However, I need to put this anonymous type inside my model and am having the following conversion problem (see image - view image with your favorite viewer).
Customer is a parent of Projects with the below models. I cannot use typed models due to the following exception in the code:
The entity or complex type 'CodeFirstNamespace.Customer' cannot be constructed in a LINQ to Entities query.
namespace YeagerTechDB.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
[Serializable, DataContract(IsReference = true)]
public partial class Customer
{
public Customer()
{
Projects = new HashSet<Project>();
}
[Key]
[ScaffoldColumn(true)]
[Display(Name = "ID")]
[DataMember]
public short CustomerID { get; set; }
[Required]
[StringLength(256)]
[DataMember]
public string UserName { get; set; }
[Required]
[StringLength(50)]
[EmailAddress]
[DataMember]
public string Email { get; set; }
[StringLength(50)]
[DataMember]
public string Company { get; set; }
[StringLength(50)]
[DataMember]
public string FirstName { get; set; }
[StringLength(50)]
[DataMember]
public string LastName { get; set; }
[StringLength(50)]
[DataMember]
public string Address1 { get; set; }
[StringLength(50)]
[DataMember]
public string Address2 { get; set; }
[StringLength(50)]
[DataMember]
public string City { get; set; }
[StringLength(2)]
[DataMember]
public string State { get; set; }
[StringLength(10)]
[DataType(DataType.PostalCode)]
[RegularExpression(#"^\d{5}(-\d{4})?$", ErrorMessage = "Must match 99999 or 99999-9999 format")]
[DataMember]
public string Zip { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
[RegularExpression(#"^\s*([\(]?)\[?\s*\d{3}\s*\]?[\)]?\s*[\-]?[\.]?\s*\d{3}\s*[\-]?[\.]?\s*\d{4}$", ErrorMessage = "Must match 999-999-9999 format")]
[DataMember]
public string HomePhone { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
[RegularExpression(#"^\s*([\(]?)\[?\s*\d{3}\s*\]?[\)]?\s*[\-]?[\.]?\s*\d{3}\s*[\-]?[\.]?\s*\d{4}$", ErrorMessage = "Must match 999-999-9999 format")]
[DataMember]
public string CellPhone { get; set; }
[StringLength(100)]
[DataType(DataType.Url)]
[DataMember]
public string Website { get; set; }
[StringLength(50)]
[DataType(DataType.Url)]
[DataMember]
public string IMAddress { get; set; }
[DataType(DataType.DateTime)]
[Display(Name = "Created")]
[DataMember]
public DateTime CreatedDate { get; set; }
[Display(Name = "Updated")]
[DataType(DataType.DateTime)]
[DataMember]
public DateTime? UpdatedDate { get; set; }
[DataMember]
public virtual ICollection<Project> Projects { get; set; }
}
}
namespace YeagerTechDB.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
[Serializable, DataContract(IsReference = true)]
public partial class Project
{
[Key]
[ScaffoldColumn(false)]
[Editable(false)]
[Display(Name = "Proj ID")]
[DataMember]
public short ProjectID { get; set; }
[ScaffoldColumn(false)]
[Editable(true)]
[Display(Name = "Cust ID")]
[DataMember]
public short CustomerID { get; set; }
[Required(ErrorMessage = "Required!")]
[StringLength(30)]
[Display(Name = "Project Name")]
[DataMember]
public string Name { get; set; }
[Required]
[DataType(DataType.MultilineText)]
[DataMember]
public string Description { get; set; }
[ScaffoldColumn(true)]
[Display(Name = "Category")]
[DataMember]
public short CategoryID { get; set; }
[ScaffoldColumn(true)]
[Display(Name = "Priority")]
[DataMember]
public short PriorityID { get; set; }
[ScaffoldColumn(true)]
[Display(Name = "Status")]
[DataMember]
public short StatusID { get; set; }
[DataType(DataType.Currency)]
[DataMember]
public decimal? Quote { get; set; }
[DataType(DataType.MultilineText)]
[DataMember]
public string Notes { get; set; }
[DataType(DataType.DateTime)]
[Display(Name = "Created")]
[DataMember]
public DateTime CreatedDate { get; set; }
[DataType(DataType.DateTime)]
[Display(Name = "Updated")]
[DataMember]
public DateTime? UpdatedDate { get; set; }
[DataMember]
public virtual Category Category { get; set; }
[DataMember]
public virtual Customer Customer { get; set; }
[DataMember]
public virtual Priority Priority { get; set; }
[DataMember]
public virtual Status Status { get; set; }
[DataMember]
public virtual ICollection<TimeTracking> TimeTrackings { get; set; }
}
}

Override MetaData UIHint in Derived Class

EF creates the Item class, I then create a partial Item class with a metadataType, ItemMD.
In certain cases, I want to use the UIHint defined in ItemMD, but in others, I want to override the UIHint to use another editor. So I try creating a derived class that inherits ItemMD....but I don't think this is how you are supposed to do it. It compiles, but I get inconsistent behaviour....when I have 5 fields in my Razor form, 4 are using the base ItemMD UIHint and 1 is using the derived class UIHint. Not sure why the inconsistency.
[MetadataType(typeof(ItemMD))]
public partial class Item : AuditStamps, IEntity, IAuditStamps
{
}
public partial class ItemMD
{
public int Id { get; set; }
[Display(Name = "Company Id")]
public int CompanyId { get; set; }
public string Description { get; set; }
[Display(Name = "Short Description")]
public string ShortDescription { get; set; }
[Display(Name = "Type")]
[UIHint("ItemAtrributesComboBox")]
public virtual string Attribute1 { get; set; }
[Display(Name = "Color")]
[UIHint("ItemAtrributesComboBox")]
public virtual string Attribute2 { get; set; }
[Display(Name = "Finish")]
[UIHint("ItemAtrributesComboBox")]
public virtual string Attribute3 { get; set; }
[Display(Name = "Texture")]
[UIHint("ItemAtrributesComboBox")]
public virtual string Attribute4 { get; set; }
[Display(Name = "Gauge")]
[UIHint("ItemAtrributesComboBox")]
public virtual string Attribute5 { get; set; }
public class ItemSearchFiltersViewModel : OTIS.domain.InventoryMgmt.Item.ItemMD
{
[Display(Name = "Type:")]
[UIHint("ItemAttributesDDL")]
public override string Attribute1 { get; set; }
[Display(Name = "Color:")]
[UIHint("ItemAttributesDDL")]
public override string Attribute2 { get; set; }
[Display(Name = "Finish:")]
[UIHint("ItemAttributesDDL")]
public override string Attribute3 { get; set; }
[Display(Name = "Texture:")]
[UIHint("ItemAttributesDDL")]
public override string Attribute4 { get; set; }
[Display(Name = "Gauge:")]
[UIHint("ItemAttributesDDL")]
public override string Attribute5 { get; set; }
}

Categories