Overriding the default date format validation on the AccountModel in MVC4 Application - asp.net-mvc-4

I have created a windows form based application and am using the simple membership AccountModel. On the registration form I am having problems with the date format when the application is uploaded to azure.
Locally I am able to enter the format "31/10/2013" but on the azure hosted application I must enter it in the format "10/31/2013". How can I override the validation so that it allows the use of DD/MM/YYYY format
My register model is as follows:
public class RegisterModel
{
[Required]
[Display(Name = "Username")]
public string UserName { get; set; }
[Required]
[Display(Name = "Forename")]
public string Forename { get; set; }
[Required]
[Display(Name = "Surname")]
public string Surname { get; set; }
[Required]
[Display(Name = "DOB")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd.MM.yyyy}")]
public DateTime DOB { 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 and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Secret Answer")]
public string SecretAnswer { get; set; }
}
I tried applying a dateformat to the DOB property as above but on azure it is still validating against MM/DD/YYYY

The FormatAttribute of the Mvc Controls Toolkit enables the developer to define the format to be used in the representation of a property on the client side, as shown in the example below :-
Format(Prefix="Date of birth is: ", ClientFormat = "d", NullDisplayText="No date of birth available")]
public DateTime? BirthDate { get; set; }
This way, the strings can be globalized as explained here.
Below the list of all supported date format:
Format Meaning "en-US"
f Long Date, Short Time dddd, MMMM dd, yyyy h:mm tt
F Long Date, Long Time dddd, MMMM dd, yyyy h:mm:ss tt
G Short Date, Long Time M/d/yyyy h:mm:ss tt
t Short Time h:mm tt
T Long Time h:mm:ss tt
d Short Date M/d/yyyy
D Long Date dddd, MMMM dd, yyyy
Y Month/Year MMMM, yyyy
M Month/Day yyyy MMMM

Related

asp.net MVC: TryUpdateModel doesn't bind DateTime properly

I'm having issues with a date property not binding correctly using TryUpdateModel in MVC.
I am using a POCO class and a corresponding viewModel.
public class ContactModel
{
public int Id { get; set; }
[Display(Name = "First Name")]
[StringLength(50)]
[Required(ErrorMessage = "First name must be entered.")]
public string ContactGivenName { get; set; }
[Display(Name = "Last Name")]
[StringLength(50)]
[Required(ErrorMessage = "Last name must be entered.")]
public string ContactFamilyName { get; set; }
....
[Display(Name = "Date of Birth")]
public DateTime? DateOfBirth { get; set; }
}
the entity class:
public class Contact
{
[Key]
public int Id { get; set; }
[StringLength(50)]
[Column(TypeName = "varchar")]
public string ContactFamilyName { get; set; }
[StringLength(50)]
[Column(TypeName = "varchar")]
public string ContactGivenName { get; set; }
...
[Column(TypeName = "date")]
public DateTime? DateOfBirth { get; set; }
}
and in my controller :
[HttpPost]
[GridAction]
public virtual ActionResult UpdateContact(int id, FormCollection form)
{
//Find a customer whose CustomerID is equal to the id action parameter
var c = _contactService.Get(id);
if (c != null)
{
//Perform model binding (fill the customer properties and validate it).
if (TryUpdateModel(c, form))
{
The _contactService.Get returns the instance from EntityFramework.
The TryUpdateModel binds string properties like first and last name correctly, but despite a lot of tries, I can't get it to bind the date of birth.
I suspect it's a formatting issue of some kind but cannot find what it is.
When I debug, I can see in the FormCollection that the date is correctly there, with the value that was input in the view so the data is definitely passed on to the controller.
the value passed to the controller is in format :
yyyy-MM-dd
I tried modifying this on the fly with multiple format without success.
Any ideas what I'm doing wrong here ?
Thanks a lot
Well, first, I have no idea why you're using TryUpdateModel.. That's pretty archaic.
Second, it sounds to me like you have not set your culture to accept the format you expect. Add the following to your web.config if your browser is defaults already set to the correct culture:
<system.web>
<globalization culture="auto" uiculture="auto" enableclientbasedculture="true">
</globalization>
</system.web>
If you want to force a culture, then set the culture you wish in this setting.
the globalization didn't help and is actually already set, however I realized there's a custom binder for Datetime and that is probably where my problem is.
thanks

How save the time of last log in using the SimpleMembership?

I need to save the time, when user loged in.
First I try to realize it in AccountController Login. But now I know, that isn't possible, because User.Id is -1.
Ok, and what can I do to save the time in my user table?
The next problem for me is, when do it. The informations I need to get the user are created after redirect. And the redirect can go everywhere.
An idea is, to get the time on which the ASPXAUTH cookie is set, but I don't know, how to get it.
Is there any solution?
If you need only last login time, you may receive that infrimation from SimpleMembership:
var User = Membership.GetUser("Username") // get user by name
DateTime LastActivityDate = User.LastActivityDate; // get last activity date and time
DateTime LastLogin = User.LastLoginDate; // Last login date and time
DateTime LastPasswordChange = User.LastPasswordChangedDate;
Just learning this stuff myself.
You need to extend the AccountModel, in AccountModel.cs
For example, I added Email to my UserProfile table generation.
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
}
public string Email { get; set; }
I also needed to add it to my RegisterModel further down the file
public class RegisterModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[Display(Name = "Email Address")]
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 and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
The important part here is this new entry:
[Required]
[Display(Name = "Email Address")]
public string Email { get; set; }
Then I needed to add the Email information to the RegisterView, which is exactly the same as doing it with the other parts, since it is now part of the model.
One of the most important parts comes when you're saving the information back into the database. In my Register Action, I have the WebSecurity.CreateUserAndAccount method which was already defined. It requires tweaks however, to be able to add EXTRA information to the database with this method.
Thankfully one of the overloads allows passing in a dictionary to the extra data.
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email }, false);
new { Email = model.Email }
If you don't already have the column added in your database, I don't think it will pick it up. You need to make sure that column exists, so get it set up before hand.

Time Input Field in ASP.NET MVC

I'm having trouble trying to write a form with time field using ASP.NET MVC 4.
Model:
class Abcde {
[DataType(DataType.Time)]
public DateTime ATime { get; set; }
}
View.cshtml
...
#Html.EditorFor(m => m.ATime)
#Html.ValidationMessageFor(m => m.ATime)
The validation always failed when I tried to input a time (hh:nn:ss), and said it was not in the corrent format, so i have to input a date instead.
My Question is should I change the type to TimeSpan? Or is there any other way?
[Required]
[DataType(DataType.Time)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:H:mm}")]
public DateTime Time { get; set; }`
Try this, you can format in the DataFormatString the way you want it to work for you, im using it in a project now and it's working for me.
Actually this is what worked for me.
[DataType(DataType.Time)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
public DateTime Hour { get; set; }
[Required]
[DataType(DataType.Time)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
public DateTime Time { get; set; }
This code is correct. But it only works when you use EditorFor instead of TextBoxFor.
Use:
[Required]
[DataType(DataType.Time)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm:ss}")]
public DateTime FieldTime{ get; set; }
You need to match your date validation with the format that works internally for this annotation. So, adding the ApplyFormat passing a String Pattern you can get it.

How to start an ID value from a set number with ASP mvc 4 model class

I want to create a class where the ID value can start from 8000 so that it wont conflict with any other IDs from other tables/models.
Here's my model
public class Employee
{
[Required]
[Range(8000,10000)]
public long Id { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
[Display(Name = "Phone ")]
public string PhoneNumber { get; set; }
public virtual Address Address { get; set; }
[DataType(DataType.EmailAddress)]
[Display(Name = "E-mail")]
public string Email { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Date of Birth", Prompt="MM/DD/YYYY")]
public DateTime dateOfBirth { get; set; }
public virtual IEnumerable<Availability> availability {get;set;}
}
Model attributes don't set values - they validate them. If you are concerned with Primary Key Identity inserts, then change your key from an integer to a GUID. Setting and arbitrary 8000 limit will seriously limit scalability and protability in the future.

Castle Validators how to Validate Is Lesser/Greater Than Or Equal

I see the ValidateIsLesser and ValidateIsGreater attributes. But what if I want to do a ValidateIsLesserOrEqual and/or ValidateIsGreaterOrEqual. Do I just need to write these custom attributes or is there pre-built capabilities for this that I am having a hard time finding?
[ValidateNonEmpty]
[ValidateDate]
[ValidateIsLesser(IsLesserValidationType.Date, "EndDate", "Start Date must be before End Date.")]
public DateTime StartDate { get; set; }
[ValidateNonEmpty]
[ValidateDate]
[ValidateIsGreater(IsGreaterValidationType.Date, "StartDate", "End Date must be after the Start Date.")]
public DateTime EndDate { get; set; }
You can use the ValidateSelf attribute and supply your own validation for the OrEqual comparisons:
[ValidateNonEmpty]
[ValidateDate]
public DateTime StartDate { get; set; }
[ValidateNonEmpty]
[ValidateDate]
public DateTime EndDate { get; set; }
[ValidateSelf]
public void ValidateDate(ErrorSummary errors)
{
if (StartDate >= EndDate)
errors.RegisterErrorMessage("StartDate", "Start date must be earlier than end date.");
}