ASP.NET MVC4 Validation - asp.net-mvc

I have a View model
public class TrainingProgramScheduledDateVM
{
public bool IsTuesday { get; set; }
[DataType(DataType.Time)]
public string TueStartTime { get; set; }
[DataType(DataType.Time)]
public string TueEndTime { get; set; }
public bool IsWednesday { get; set; }
[DataType(DataType.Time)]
public string WedStartTime { get; set; }
[DataType(DataType.Time)]
public string WedEndTime { get; set; }
public bool IsThursday { get; set; }
[DataType(DataType.Time)]
public string ThuStartTime { get; set; }
[DataType(DataType.Time)]
public string ThuEndTime { get; set; }
}
I want to put the validation i a way that.
1- If IsTuesday = true Then TueStartTime and TueEndTime should Requires.
and so on for other
2- At least one boolean value should be true and relevant time should be required.
please suggest me any easy way.
Thanks

Use remote validation. For example, Here
[Remote(
"doesProductNameExistUnderCategory",
"Northwind",
AdditionalFields = "Category_ID",
ErrorMessage = "Product name already exists under the chosen category. Please enter a different product name.",
HttpMethod = "POST"
)]
[Required]
public string Product_Name { get; set; }

I see repetition. This block:
public bool IsTuesday { get; set; }
[DataType(DataType.Time)]
public string TueStartTime { get; set; }
[DataType(DataType.Time)]
public string TueEndTime { get; set; }
Can better be abstracted into its own type, like:
public class ScheduleDate
{
public DayOfWeek DayOfWeek { get; set; }
public bool IsSelected { get; set; }
[DataType(DataType.Time)]
[RequiredIf(IsSelected)]
public string StartTime { get; set; }
[DataType(DataType.Time)]
[RequiredIf(IsSelected)]
public string EndTime { get; set; }
}
Then your TrainingProgramScheduledDateVM can contain a list of ScheduleDate objects.

Related

Country and City Dropdown in ASP.NET Core MVC with db-first approach

I know this question might be asked so many times, I tried a lot to find the answer and ultimately I am throwing it here if some one can help me.
I am doing a project in ASP.NET Core MVC with a database-first approach. I have a registration form where I need to populate Country and City dropdowns to fill with data coming in through WeCareConext class.
In my controller I am doing this:
[HttpGet]
public IActionResult Register()
{
CompanyEditViewModel model = new CompanyEditViewModel();
var fromDatabaseEF = new SelectList(_context.Country.ToList(), "CountryId", "NameEn");
ViewData["CompanyRegister"] = fromDatabaseEF;
return View(model);
}
My Country model:
public partial class Country
{
public Country()
{
City = new HashSet<City>();
Currency = new HashSet<Currency>();
HolidayType = new HashSet<HolidayType>();
Holidays = new HashSet<Holidays>();
Province = new HashSet<Province>();
StaffInfo = new HashSet<StaffInfo>();
}
public int CountryId { get; set; }
public string NameAr { get; set; }
public string NameEn { get; set; }
public string NameFr { get; set; }
public string IsoCode2 { get; set; }
public string IsoCode3 { get; set; }
public string RegionAr { get; set; }
public string Region { get; set; }
public byte? PostcodeRequired { get; set; }
public bool? IsActive { get; set; }
public byte? IsAvailable { get; set; }
public string MobileMask { get; set; }
public byte? IsDeleted { get; set; }
public int? BaseCharges { get; set; }
public int? MobileNumberLength { get; set; }
public string CountryCode { get; set; }
public byte[] IconImage { get; set; }
public string PickerListAr { get; set; }
public string PickerListEn { get; set; }
public string PickerListFr { get; set; }
public virtual ICollection<City> City { get; set; }
public virtual ICollection<Currency> Currency { get; set; }
public virtual ICollection<HolidayType> HolidayType { get; set; }
public virtual ICollection<Holidays> Holidays { get; set; }
public virtual ICollection<Province> Province { get; set; }
public virtual ICollection<StaffInfo> StaffInfo { get; set; }
}
My CompanyEditViewModel class:
public class CompanyEditViewModel
{
[Display(Name = "Company Number")]
public string CompanyId { get; set; }
[Required]
[Display(Name = "Company Name")]
[StringLength(75)]
public string Name { get; set; }
[Required]
[Display(Name = "Country")]
public string CountryId { get; set; }
public IEnumerable<SelectListItem> Countries { get; set; }
[Required]
[Display(Name = "City")]
public string SelectedCityCode { get; set; }
public IEnumerable<SelectListItem> Cities { get; set; }
}
Unfortunately, this returns an error:
System.ArgumentException: 'Format of the initialization string does not conform to specification starting at index 0.'
I am trying different approaches but not solving my issue. Can anyone suggest some code which can help me and I can also select country and then populate city dropdown according to the CountryID without page reload ? Thanks in advance.

Object reference error when getting data from database

My portal has worked fine for several years but nowadays I have problems with my some codes. I want to update my code but at the first step I have problems with login page. when I use FirstOrDefault I got error on object reference while the list is filled and contains 1 user.
int g = db.sp_GetUserData_ByUserName(model.UserName.Trim()).Count();
//it shows 1
OSUserData userData1 = db.sp_GetUserData_ByUserName(model.UserName.Trim()).FirstOrDefault();
I didn't change this code and It works perfectly on the portal. However, I can't run it on my development server.
I checked again and I found that OSUserData constructor throws exception : Enumeration yielded no result. this is my class code :
public OSUserData()
{
this.OSUploadedFilesMultipleUsers = new HashSet<OSUploadedFilesMultipleUser>();
this.OSSalaryLists = new HashSet<OSSalaryList>();
this.OSUploadedFiles = new HashSet<OSUploadedFile>();
}
public int Id { get; set; }
public string Address { get; set; }
public string BranchCode { get; set; }
public string BranchParentNationalCode { get; set; }
public string CitName { get; set; }
public string City { get; set; }
public string CompanyName { get; set; }
public string CouName { get; set; }
public string Country { get; set; }
public string FaxNo { get; set; }
public string FollowCode { get; set; }
public string Hozeh { get; set; }
public Nullable<bool> IsBranch { get; set; }
public string LoginStatus { get; set; }
public string NationalCode { get; set; }
public string NewEconomicNo { get; set; }
public string Oldeconomicno { get; set; }
public string PostalCode { get; set; }
public string ProIdTTMS { get; set; }
public string ProName { get; set; }
public string Provision { get; set; }
public string RegistrationNo { get; set; }
public string State { get; set; }
public string TaxOfficeCode { get; set; }
public string TaxPayerType { get; set; }
public string TelCode { get; set; }
public string TelNo { get; set; }
public string TprId { get; set; }
public string UserName { get; set; }
public bool Validate { get; set; }
public bool Disabled { get; set; }
public string OwnerShipTypeDesc { get; set; }
public Nullable<byte> OwnerShipTypeCode { get; set; }
public bool Processed { get; set; }
public bool CheckedUser { get; set; }
public bool Blocked { get; set; }
public virtual ICollection<OSUploadedFilesMultipleUser> OSUploadedFilesMultipleUsers { get; set; }
public virtual ICollection<OSSalaryList> OSSalaryLists { get; set; }
public virtual ICollection<OSUploadedFile> OSUploadedFiles { get; set; }
You are trying to add to a null/unreferenced/not initialized object/list. Initialize first the list
List<OSUserData> userData1 = new List<OSUserData>();
Then add it
var user = db.sp_GetUserData_ByUserName(model.UserName.Trim()).FirstOrDefault();
userData1.Add(new OSUserData{
Prop1 = user.Prop1,
Prop2 = user.Prop2,
......
});
Or if you only want one user, just make it var
var user = db.sp_GetUserData_ByUserName(model.UserName.Trim()).FirstOrDefault();

Query and display in one view data coming from many to many with payload in Entity framework 6

I have this complex model:
public class Food
{
[Key]
public int FoodID { get; set; }
[Required]
[DisplayName("Food Name")]
public string FoodNameEN { get; set; }
[Required]
[DisplayName("Food Name")]
public string FoodNameFR { get; set; }
[Required]
[DisplayName("Food Name")]
public string FoodNameNL { get; set; }
[Required]
[DisplayName("Food Description")]
public string FoodDescriptionEN { get; set; }
[Required]
[DisplayName("Food Description")]
public string FoodDescriptionFR { get; set; }
[Required]
[DisplayName("Food Description")]
public string FoodDescriptionNL { get; set; }
public int CategoryID { get; set; }
[Required]
public bool Availability { get; set; }
[Required]
[DisplayName("Is Menu of the Day")]
public bool DailyMenu { get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<FoodAttributeValue> FoodAttributeValues { get; set; } = new HashSet<FoodAttributeValue>();
public virtual ICollection<OrderDetail> OrderDetails { get; set; } = new HashSet<OrderDetail>();
public class Category
{
[Key]
public int CategoryID { get; set; }
[Required(ErrorMessage = "Please enter a Category Name for English")]
[DisplayName("Category Name")]
public string CategoryEN { get; set; }
[Required(ErrorMessage = "Please enter a Category Name for French")]
[DisplayName("Category Name")]
public string CategoryFR { get; set; }
[Required(ErrorMessage = "Please enter a Category Name for Dutch")]
[DisplayName("Category Name")]
public string CategoryNL { get; set; }
[Required]
public bool Availability { get; set; }
public virtual ICollection<Food> Foods { get; set; } = new HashSet<Food>();
}
public class Attribute
{
[Key]
public int AttributeID { get; set; }
public string AttributeNameEN { get; set; }
public string AttributeNameFR { get; set; }
public string AttributeNameNL { get; set; }
public virtual ICollection<AttributeValue> AttributeValues { get; set; } = new HashSet<AttributeValue>();
}
public class AttributeValue
{
[Key]
public int AttributeValueID { get; set; }
public int AttributeID { get; set; }
public string AttributeValueEN { get; set; }
public string AttributeValueFR { get; set; }
public string AttributeValueNL { get; set; }
public virtual Attribute Attribute { get; set; }
public virtual ICollection<FoodAttributeValue> FoodAttributeValues { get; set; } = new HashSet<FoodAttributeValue>();
}
public class FoodAttributeValue
{
[Key]
[Column(Order = 0), ForeignKey("Food")]
public int FoodID { get; set; }
[Key]
[Column(Order = 1), ForeignKey("AttributeValue")]
public int AttributeValueID { get; set; }
public decimal Price { get; set; }
public string CreatorUserName { get; set; }
public DateTime DateCreated { get; set; }
public virtual Food Food { get; set; }
public virtual AttributeValue AttributeValue { get; set; }
}
Attributes contains an attribute type like size or volume
AttributeValue contains the values for an attribute, like Normal Size, or Large.
FoodAttributeValue is a many to many table with payload "Price". So basically, the same Food comes in different sizes with different Prices.
My DatabaseContext:
public class ModelContext: DbContext
{
public DbSet<Category> Categories { get; set; }
public DbSet<Food> Foods { get; set; }
public DbSet<Attribute> Attributes { get; set; }
public DbSet<AttributeValue> AttributesValues { get; set; }
public DbSet<FoodAttributeValue> FoodAttributeValues { get; set; }
}
How can i query the model using linq, with the intention to have on the same view, the list of Foods that contain also the Attributes of the Food, the AttributeValues of it and eventually the Price?
Thanks in advance!
In MVC it is a best practice to create a ViewModel (or DTO) designed for the view you want to display. Generally, try to avoid using your entity POCOs in the view.
So for example:
public class FoodIndexViewModel
{
// Add the various entity fields you want here.
public int FoodID { get; set; }
...
// Take all these annotations out of your entity model. They belong here.
[Required]
[DisplayName("Food Name")]
public string FoodNameEN { get; set; }
...
[Required(ErrorMessage = "Please enter a Category Name for English")]
[DisplayName("Category Name")]
public string CategoryEN { get; set; }
public decimal Price { get; set; }
... etc. etc.
}
Now you can compose a LINQ query to populate the view model. AutoMapper can greatly ease this process.
var listOfFoodsVM = context.Foods
.Where(food => food.Availability)
.Select(food => new FoodIndexViewModel
{
FoodId = food.FoodId,
FoodNameEN = food.FoodNameEN,
... // other fields from food
CategoryEN = food.Category.CategoryEN,
// Here you would either pick a single value from the list based on your criteria
Price = food.FoodAttributeValues.FirstOrDefault(fav => fav.AttributeValueID == 1).Price
// or you could include a collection of FoodAttributes in your viewmodel:
FoodAtributes = food.FoodAttributes
... etc.
}).ToList();
Now you pass this into your view.
return View(listOfFoodsVM );

Automapper with nested entity not working

I have two classes which are mentioned below. I am trying to map those through Auto Mapper but it is not working.
public class VMTemplates
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Path { get; set; }
public bool IsActive { get; set; }
public System.DateTime TimeStamp { get; set; }
public virtual ICollection<VMTemplateGroup> VMTemplateGroup { get; set; }
}
public VMTemplateViewModel()
{
VMTemplateGroup = new List<VMTemplateGroupViewModel>();
}
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
public string Path { get; set; }
public bool IsActive { get; set; }
[Required(ErrorMessage = "Please Upload File")]
[Display(Name = "Upload File")]
[ValidateFile]
public HttpPostedFileBase TemplateUpload { get; set; }
public System.DateTime TimeStamp { get; set; }
public List<VMTemplateGroupViewModel> VMTemplateGroup { get; set; }
I am using this code to map them
confi.CreateMap<VMTemplateViewModel, VMTemplates>().ReverseMap();
confi.CreateMap<VMTemplateGroupViewModel, VMTemplateGroup>().ReverseMap();
calling code
public VMTemplates GetVMTemplateById(int id)
{
return DataContext.VMTemplates.Include("VMTemplateGroup").Where(a => a.Id == id).FirstOrDefault();
}
This is where exception happens. I get stack overflow exception
public VMTemplateViewModel GetVMTemplateById(int templateId)
{
var result = _vmTemplateRepository.GetVMTemplateById(templateId);
return _autoMapperService.MapEntity<VMTemplateViewModel>(result);
}

Html.ValidationSummary shows but I have not Required attribute

I have a model.
it looks like this
public class AddEditNotificationViewModel : BaseViewModel
{
public TimeSpan TimeOfDayToRun { get; set; }
public string[] DaysRunning { get; set; }
public string Id { get; set; }
public string CampaignId { get; set; }
public int ForHowManyWeeks { get; set; }
public DateTimeOffset StartDate { get; set; }
public bool RunForever { get; set; }
public string TimeZone { get; set; }
}
I have this #Html.ValidationSummary( false ) in my view.
It shows erros for 3 properties, but I have no Required attribute on them.
Seems spooky ?
The value types (like bool and int) are considered as Required by default, unless you use a Nullable<T> type.
In your model, TimeOfDayToRun, ForHowManyWeeks and RunForever are non-nullable value types. If you replace the type of TimeOfDayToRun with Nullable<TimeSpan> or TimeSpan?, you're telling MVC binder to allow null values, and there won't be any validation errors.
Try the following model:
public class AddEditNotificationViewModel : BaseViewModel
{
public TimeSpan? TimeOfDayToRun { get; set; }
public string[] DaysRunning { get; set; }
public string Id { get; set; }
public string CampaignId { get; set; }
public int? ForHowManyWeeks { get; set; }
public DateTimeOffset StartDate { get; set; }
public bool? RunForever { get; set; }
public string TimeZone { get; set; }
}

Resources