I am new to MVC 3 Data Annotations and I just want to ask that if its possible to add Validation on a Group of Fields in Model and Display the validation if none of it has Value?
this is the set of fields in my Data model
public class ContactModel
{
public Nullable<int> Id { get; set; }
[Display(Name = "Contact Firstname")]
[Required(ErrorMessage = "Required!")]
public string ContactFirstname { get; set; }
[Display(Name = "Contact Lastname")]
[Required(ErrorMessage = "Required!")]
public string ContactLastname { get; set; }
[Display(Name = "Contact Middlename")]
public string ContactMiddlename { get; set; }
[Display(Name = "Phone")]
[Required(ErrorMessage = "Required!")]
public string ContactPhone { get; set; }
[Display(Name = "Mobile ")]
[Required(ErrorMessage = "Required!")]
public string ContactMobile { get; set; }
[Display(Name = "Email")]
[Required(ErrorMessage = "Required!")]
public string ContactEmail { get; set; }
[Display(Name = "Job Title")]
[StringLength(50, ErrorMessage = "Max character reached!")]
public string ContactJobTitle { get; set; }
}
And I want to add validation if one from Phone,Mobile or Email doesn't have value
Thanks
You can implement IValidatableObject interface and add validation for all necessary properties:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(string.IsNullOrEmpty(Phone) || string.IsNullOrEmpty(Mobile) || string.IsNullOrEmpty(Email))
{
yield return new ValidationResult("Some error message");
}
}
Of course you should remove [Required] attributes then from those properties.
Related
Below is my State Model class.
public class State
{
[Key]
public int StateId { get; set; }
public string StateName { get; set; }
public virtual ICollection<City> Cities { get; set; }
}
Below is my City Model Class base state, city will fill.
public class City
{
[Key]
public int CityId { get; set; }
public string CityName { get; set; }
[ForeignKey("State")]
public int StateId { get; set; }
public virtual State State { get; set; }
}
Below is my Registration model class for the registration form which calls State city.
public class Registration
{
[Key]
public int Sno { get; set; }
[Required(ErrorMessage = "Name is required.")]
[Display(Name = "Full name")]
public string Fullname { get; set; }
[Display(Name = "Email Id")]
[Required(ErrorMessage = "Email is required.")]
public string EmailId { get; set; }
[Required(ErrorMessage = "Password is required.")]
public string Password { get; set; }
[Required(ErrorMessage = "Mobile is required.")]
public string Mobile { get; set; }
[Required(ErrorMessage = "Address is required.")]
public string Address { get; set; }
public int SelectedStateId { get; set; }
public int SelectedCityId { get; set; }
[Required(ErrorMessage = "Entity is required.")]
public string EntityType { get; set; }
public string Website { get; set; }
public string PinCode { get; set; }
public string accountactivated { get; set; }
public int RoleId { get; set; }
[Display(Name = "New Password")]
[NotMapped]
public string NewPassword { get; set; }
[Display(Name = "Confirm New Password")]
[NotMapped] // Does not effect with your database
[System.Web.Mvc.Compare("NewPassword", ErrorMessage = "Password not match")]
public string ConfirmNewPassword { get; set; }
}
My question is how should i have to call state and city cascading drop down list in my Registration Model class to generate scaffolding for registration page with dependent drop down list.
i have 3 models
public class UsersModel
{
[Key]
public int UserId { get; set; }
[Required]
[StringLength(100, ErrorMessage = "Invalid Name Minimum Length is 5", MinimumLength = 5)]
public string Name { get; set; }
//20150090
public int? student_ID { get; set; }
[Display(Name = "transcript")]
public string transcript { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "Invalid Name Minimum Length is 2", MinimumLength = 2)]
public string Department { get; set; }
[Required]
[Display(Name = "Phone")]
[DataType(DataType.PhoneNumber,ErrorMessage ="Invalid Phone Number")]
[Range(999999999, 9999999999)]
public int Phone { get; set; }
public int type { get; set; }
}
student
public class StudentsModel
{
[Key]
[Display(Name ="ID")]
public int StudentID { get; set; }
[Required]
public string Name { get; set; }
[Required]//20150090
public string student_ID { get; set; }
[Required]
[Display(Name = "Skills")]
public string Skills { get; set; }
[Required]
[Display(Name = "Gpa")]
[Range(1.00, 4.00, ErrorMessage = "It must be in range 0.00 to 4.00 :)")]
public float Gpa { get; set; }
[Required]
[Display(Name = "Leader")]
public string Leader { get; set; }
[Required]
[Display(Name = "transcript")]
public string transcript { get; set; }
[ForeignKey("UserId")]
public int UserId;
public UsersModel Users { get; set; }
[ForeignKey("IdeaId")]
public int? IdeaId;
public IdeaModel Idea { get; set; }
}
Idea
public class IdeaModel
{
[Required]
[Key]
public int IdeaId { get; set; }
[Required]
public string IdeaName { get; set; }
[Required]
public string IdeaDescription { get; set; }
[Required]
public string tools { get; set; }
public int? SetWith { get; set; }
[Required]
public int Prof1 { get; set; }
public int Prof2 { get; set; }
public int Prof3 { get; set; }
}
when i insert to the database user and student and idea
the foreign key in student model inserted with null value
this is the code for insertion
i want the foreign key in student model to inserted automatically
whit the values of primary key in usernodel and idea model how to make this?
public ActionResult RegisterLeader(regall reg)
{
if (ModelState.IsValid)
{
var user= db.Users.Add(reg.users);
var idea = db.Idea.Add(reg.idea);
var stu = db.Students.Add(reg.students[0]);
db.SaveChanges();
return View("RegisterLeaderPost");
//return Registerfinish();
}
}
this model have the three models
public class regall
{
public List<StudentsModel> students { get; set; }
public UsersModel users { get; set; }
public IdeaModel idea { get; set; }
}
You need to set the Idea property of the student so EF knows to make the relationship.
reg.students[0].Idea = reg.idea;
The question I had was how are models supposed to be used? I don't think I am using them correctly. Whenever I make a change to the database (user table, in this case) and rebuild the model, my changes get erased and I end up making the changes again. The changes made are adding attributes and also another column(ConfirmPassword).
Edit: I am using EF 5
This is the model that was created by the database:
using System;
using System.Collections.Generic;
public partial class User
{
public User()
{
this.Documents = new HashSet<Document>();
}
public int UserId { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string Grade { get; set; }
}
With my changes:
using System;
using System.Collections.Generic;
using CompareObsolete = System.Web.Mvc.CompareAttribute;
public partial class User
{
public User()
{
this.Documents = new HashSet<Document>();
}
[Key]
public int UserId { get; set; }
[Required]
[StringLength(15, MinimumLength = 3)]
[Display(Name = "Username*: ")]
public string Username { get; set; }
[Required]
[EmailAddress]
[StringLength(25)]
[Display(Name = "Email Address*: ")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(50, MinimumLength = 4)]
[Display(Name = "Password*: ")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm Password*: ")]
[CompareObsolete("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[Display(Name = "Your Grade*: ")]
public string Grade { get; set; }
}
1. Create UserMetaData Class
public class UserMetaData
{
[Key]
public int UserId { get; set; }
[Required]
[StringLength(15, MinimumLength = 3)]
[Display(Name = "Username*: ")]
public string Username { get; set; }
[Required]
[EmailAddress]
[StringLength(25)]
[Display(Name = "Email Address*: ")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(50, MinimumLength = 4)]
[Display(Name = "Password*: ")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm Password*: ")]
[CompareObsolete("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[Display(Name = "Your Grade*: ")]
public string Grade { get; set; }
}
2. Create new partial class in new .cs file and assign metadata class to there by using MetadataType attribute to it.
[MetadataType(typeof(UserMetaData))] // assign type of your metadata here.
public partial class User
{
}
I had been struggling with this issue since morning. I have the following class in my domain service.
[MetadataTypeAttribute(typeof(CompanyRecord.CompanyRecordMetadata))]
public partial class CompanyRecord
{
// This class allows you to attach custom attributes to properties
// of the CompanyRecord class.
//
// For example, the following marks the Xyz property as a
// required property and specifies the format for valid values:
// [Required]
// [RegularExpression("[A-Z][A-Za-z0-9]*")]
// [StringLength(32)]
// public string Xyz { get; set; }
internal sealed class CompanyRecordMetadata
{
// Metadata classes are not meant to be instantiated.
private CompanyRecordMetadata()
{
}
public Nullable<char> AccessToClearance { get; set; }
public Nullable<char> AccessToMarketplace { get; set; }
public Nullable<bool> Active { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public Nullable<int> AllotedHDSpace { get; set; }
public string City { get; set; }
public int CompanyID { get; set; }
public Binary CompanyLogo { get; set; }
[Required(ErrorMessage = "Company Name is required and must be unique.")]
public string CompanyName { get; set; }
[Range(1, Int32.MaxValue, ErrorMessage = "Company Type is required.")]
public int CompanyTypeID { get; set; }
[Range(1, Int32.MaxValue, ErrorMessage = "Country is required.")]
public Nullable<int> CountryID { get; set; }
public string Description { get; set; }
//[RegularExpression(pattern: #"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|tv|COM|ORG|NET|GOV|MIL|BIZ|INFO|MOBI|NAME|AERO|JOBS|MUSEUM|TV|Com|Org|Net|Gov|Mil|Biz|Info|Mobi|Name|Aero|Jobs|Museum|Tv)\b", ErrorMessage = "Please provide a valid email address")]
[RegularExpression(pattern: #"(\w[-._\w]*\w#\w[-._\w]*\w\.[a-zA-z]{2,6})", ErrorMessage = "Please provide a valid email address")]
public string EmployeeEmail { get; set; }
//[RegularExpression(pattern: #"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|tv|COM|ORG|NET|GOV|MIL|BIZ|INFO|MOBI|NAME|AERO|JOBS|MUSEUM|TV|Com|Org|Net|Gov|Mil|Biz|Info|Mobi|Name|Aero|Jobs|Museum|Tv)\b", ErrorMessage = "Please provide a valid email address")]
//(\w[-._\w]*\w#\w[-._\w]*\w\.\w{2,3})
[RegularExpression(pattern: #"(\w[-._\w]*\w#\w[-._\w]*\w\.[a-zA-z]{2,6})", ErrorMessage = "Please provide a valid email address")]
[Required(ErrorMessage = "Email is required.")]
public string Email { get; set; }
[StringLength(10, ErrorMessage = "Phone Ext. should not be more than 10 chars.")]
public string EmployeePhoneExt { get; set; }
[StringLength(20, ErrorMessage = "Phone No. should not be more than 20 chars.")]
[RegularExpression(pattern: #"^[0-9\-\(\) ]*[0-9\-\(\)]*$", ErrorMessage = "Please provide a valid Phone No.")]
public string EmployeePhoneNo { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Range(0, int.MaxValue, ErrorMessage = "Number of projects should be lower than 2,147,483,647.")]
public Nullable<int> NoOfProjects { get; set; }
public Nullable<int> NoOfUsers { get; set; }
[StringLength(10, ErrorMessage = "Phone Ext. should not be more than 10 chars.")]
public string PhoneExt { get; set; }
[StringLength(20, ErrorMessage = "Phone No. should not be more than 20 chars.")]
[Required(ErrorMessage = "Phone No. is required.")]
[RegularExpression(pattern: #"^[0-9\-\(\) ]*[0-9\-\(\)]*$", ErrorMessage = "Please provide a valid Phone No.")]
public string PhoneNo { get; set; }
[RegularExpression(pattern: #"^[a-zA-Z0-9\-\(\)\* ]*[a-zA-Z0-9\-\(\)\*]*$", ErrorMessage = "Postal codes cant' contain special characters except for -, (, ), * and spaces.")]
public string PostalCode { get; set; }
public string Province { get; set; }
public string Website { get; set; }
public int MarketID { get; set; }
public int AffiliationID { get; set; }
public string CallLetter { get; set; }
}
}
PROBLEM: I need to create a validation rule that woudl require MarketID and Affiliation ID only when CompanyTypeID is equivalent to 1, 3, 5, 9 and 11 is there someone out there who has an idea on how to solve this?
You should use the custom validation.
There are some topics for your question below:
1 http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.customvalidationattribute(vs.95).aspx
2 http://blogs.microsoft.co.il/blogs/bursteg/archive/2009/04/14/net-ria-services-custom-validation.aspx
I'm trying to write a method that generates multiple commission slips. This is for a college, where clients are enrolled with tutors in a class called Enrollments. With this method, I am trying to accumulate the monthly fee of the tutors' clients multiplied by their commission percentages, as tutors earn a certain commission on the lessons they give. Here is my code for this:
public ActionResult CreateBulkCommissions()
{
var month = DateTime.Now.ToString("MMMM");
var enrolments = db.Enrollments.ToList();
var newCommissions = from enrolment in enrolments
select new TutorCommission()
{
CommissionAmount = enrolment.MonthlyFee,
CommissionMonth = month, // string constant
CommissionStatus = "Unpaid",
Tutor = enrolment.Tutor
};
foreach (var newCommission in newCommissions)
{
List<TutorCommission> TutorComs = newCommissions.GroupBy(g => g.Tutor).Select(s => new TutorCommission
{
CommissionAmount = s.Sum(u => u.CommissionAmount) * s.Key.TutorCommissionPercentage,
TutorNoID = s.Key.TutorNoID
}).ToList();
db.TutorCommission.Add(newCommission);
db.SaveChanges();
}
return RedirectToAction("Index");
}
The problem is that TutorCommission entries are created for each individual enrollment, instead of one entry per tutor (for the month) with the total commission amount. I.e. Ashley has 3 clients and therefore 3 enrollments and currently 3 TutorCommission entries are being created for him. I want to add up the enrollments amounts for one entry. In addition, the amount is not being multiplied by the commission percentage, so it is just saving as the full enrollment monthly fee. Relevant classes are:
public class Enrollment
{
[Key]
[Display(Name = "Enrollment ID Number")]
public long EnrollmentIDNumber { get; set; }
[Display(Name = "Client ID Number")]
public long ClientNumberID { get; set; }
[Display(Name = "Tutor ID Number")]
public long TutorNoID { get; set; }
[Display(Name = "Course Name")]
public string CourseName { get; set; }
[Display(Name = "Lesson Time")]
public string LessonTime { get; set; }
[Display(Name = "Lesson Day")]
public string LessonDay { get; set; }
[Display(Name = "Lesson Location")]
public string LessonLocation { get; set; }
[Display(Name = "Lesson Type")]
public string LessonType { get; set; }
[Display(Name = "Lesson Level")]
public string LessonLevel { get; set; }
[Display(Name = "Monthly Fee")]
public long MonthlyFee { get; set; }
public virtual Client Client { get; set; }
public virtual Tutor Tutor { get; set; }
}
public class TutorCommission
{
[Key]
[Display(Name = "Commission ID")]
public long CommissionID { get; set; }
[Display(Name = "Commission Month")]
public string CommissionMonth {get; set;}
[Display(Name = "Commission Amount")]
public double CommissionAmount { get; set; }
[Display(Name = "Commission Status")]
public string CommissionStatus { get; set; }
[Display(Name = "Tutor ID Number")]
public long TutorNoID { get; set; }
public virtual Tutor Tutor { get; set; }
public virtual ICollection<CommissionPayments> CommissionPayments { get; set; }
}
public class Tutor
{
[Key]
[Display(Name = "Tutor ID Number")]
public long TutorNoID { get; set; }
[Required]
[StringLength(50, ErrorMessage="First name must be less than 50 characters")]
[Display(Name = "First Name")]
public string TutorFirstName { get; set; }
[StringLength(50, ErrorMessage = "Last name must be less than 50 characters")]
[Display(Name = "Last Name")]
public string TutorLastName { get; set; }
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[Display(Name = "Birth Date")]
public DateTime? TutorBirthDate { get; set; }
[Display(Name = "Cellphone Number")]
public string TutorCellphoneNumber { get; set; }
[Display(Name = "Home Number")]
public string TutorHomeNumber { get; set; }
[RegularExpression("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*#[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$", ErrorMessage = "Not a valid email address")]
[Display(Name = "Email Address")]
public string TutorEmailAddress { get; set; }
[Display(Name = "Street Address")]
public string TutorStreetAddress { get; set; }
[Display(Name = "Suburb")]
public string TutorSuburb { get; set; }
[Display(Name = "City")]
public string TutorCity { get; set; }
[Display(Name = "Postal Code")]
public string TutorPostalCode { get; set; }
[Display(Name="Full Name")]
public string FullName
{
get
{
return TutorFirstName + " " + TutorLastName;
}
}
[Display(Name="Commission Percentage")]
[Required]
public double TutorCommissionPercentage { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public virtual ICollection<TutorCommission> TutorCommissions { get; set; }
}
Thanks,
Amy
You can try moving the grouping logic outside the foreach loop, then iterating on the grouped list. So instead of
foreach (var newCommission in newCommissions)
{
List<TutorCommission> TutorComs = newCommissions.GroupBy(g => g.Tutor).Select(s => new TutorCommission
{
CommissionAmount = s.Sum(u => u.CommissionAmount) * s.Key.TutorCommissionPercentage,
TutorNoID = s.Key.TutorNoID
}).ToList();
db.TutorCommission.Add(newCommission);
db.SaveChanges();
}
try
List<TutorCommission> TutorComs = newCommissions.GroupBy(g => g.Tutor).Select(s => new TutorCommission
{
CommissionAmount = s.Sum(u => u.CommissionAmount) * s.Key.TutorCommissionPercentage,
TutorNoID = s.Key.TutorNoID
}).ToList();
foreach (var tutorCom in TutorComs)
{
db.TutorCommission.Add(tutorCom);
db.SaveChanges();
}
See if that is closer to the desired result.