MVC fields not required but user being told they are - asp.net-mvc-4

Title says it all. The model does not require the StartDate field but on POST I'm told it's required. It's one of several search fields, each one optional. Due to that, I'm not checking IsModel.Valid so the search works anyway, but the message shows up onscreen. If I set, in the view, #Html.ValidationSummary(true), that hides the message but the field still turns red.
Also, I do have a check to make sure EndDate is later than StartDate, so I need the messages for errors /requried fields to show up, just not when there ISN'T an error.
Here's the code:
MODEL (Partial)
[Display(Name = "Start Date")]
[DataType(DataType.Date)]
public DateTime StartDate { get; set; }
[Display(Name = "End Date")]
[GreaterThanOrEqualTo("StartDate", ErrorMessage = "End Date must be later than Start Date")]
[DataType(DataType.Date)]
public DateTime EndDate { get; set; }
VIEW (partial)
#using (Html.BeginForm()){
#Html.ValidationSummary(false)
<table>
<tr>
<td>
#Html.DisplayNameFor(m => m.StartDate)
#Html.TextBox("StartDate", "", new { #class = "datefield" })
etc.
SHARED/DISPLAY TEMPLATES
#model Nullable<DateTime>
#(Model != null ? string.Format("{0:M/d/yyyy}", Model) : string.Empty)
SHARED/EDITOR TEMPLATES
#model Nullable<DateTime>
#{
DateTime dt = DateTime.Now;
if (Model != null)
{
dt = (System.DateTime) Model;
}
#Html.TextBox("", String.Format("{0:M/d/yyyy}", dt.ToShortDateString()), new { #class = "datefield", type = "date" })
}
Some of these editors are to make a pop-up calendar work, btw.
I've tried turning on/off various things and one way or another, it still says the date fields are required. Any ideas? Thanks.

Easy way to remove validation is make int Null-able, I have already tested and it works fine. here is example:
public int? Id { get; set; }

As mentioned in the comments, value types like DateTime, int, decimal, etc. are treated as required if you don't make them nullable.
If the GreaterThanOrEqualTo attribute doesn't come from a library (such as MVC Foolproof Validation), you should let it return true if both Startdate en Enddate are null. Else you woud have to write your own custom validation attribute, but it's not that hard to do.

Related

Mudblazor DatePicker binding works one way only

I have been trying to bind mudblazor datepicker to a DateTime property using Date.
<MudDatePicker Label="Start Date" Date="#StartDate" />
<MudTextField Label="SelectedDate" #bind-Value="#StartDate" />
<MudText Typo="Typo.h3">Selected Date is: #StartDate</MudText>
#code
{
public DateTime StartDate { get; set; }
public string DateString { get; set; }
}
I have tried this code on their site and in visual studio
The code will update the Date Picker and my Text output when leaving the text field, this is normal behavior. However, I want to change the Text based on my selection of Date picker. I have tried binding to date and value. both don't reflect the selection I have made.
I have checked the documentation on their site and there is nothing on how to handle binding beyond what I am doing.
If any one knows how to bind Date picker in mudblazor please help.
Thanks
for anyone interested here is the answer:
A Date picker in Mudblazor will only bind to a nullable DateTime, and I have to use #bind-Date. So my sample code that should work looks like this:
<MudDatePicker Label="Start Date" #bind-Date="#StartDate" />
<MudTextField Label="SelectedDate" #bind-Value="#StartDate" />
<MudText Typo="Typo.h3">Selected Date is: #StartDate</MudText>
#code
{
public DateTime? StartDate { get; set; }
}
I was having a similar issue with MudDateRangePicker.
I found that I could use a nullable or a non-nullable DateRange variable but if I wanted to get the currently selected Start & End dates from a callback function, I would have to call the DateRangePicker.Close() method before I checked the dates.
Just FYI if anyone else is looking at this issue.

DateTime Field is not showing dateTime picker on MVC page [duplicate]

I am trying to populate #Html.EditorFor helper. I have created a view model with the below property
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yy}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
and my helper is set up as below (a)
#Html.ValidationMessageFor(m => m.YearBought)
#Html.EditorFor(model => model.YearBought, new { #type = "date" })
I have also tried (b)
#Html.ValidationMessageFor(m => m.YearBought)
#Html.EditorFor(model => model.YearBought.Value.Date)
Using the above format (a) nothing is displayed. Using the above format (b) 12/05/2014 00:00:00 is displayed in textbox format.
I am trying to achieve a datepicker format without a time displayed
I have reviewed several other questions but cant see what i've done different.
When I look in my database, the value is save as 2014-05-12 and when I am saving the value the EditorFor helper generates the required input facility
questions reviewed
first second third....the list goes on
EDIT
just opened the console in chrome dev tools and so this message
The specified value "12/05/14" does not conform to the required format, "yyyy-MM-dd"
I thought DisplayFormat(DataFormatString = "{0:dd/MM/yy}" was defining how to display my date?
You need to use the ISO format when using type="date"
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
This will display the date in the browsers culture.
Note there is no need to add #type = "date". The EditorFor() method will add that because of the DataType attribute. Note also that type="date" is only supported in Chrome (FireFox and IE will just generate a normal textbox)
If you do want to display the format dd/MM/yyyy in a standard textbox then you can use
#Html.TextBoxFor(m => m.YearBought, "{0:dd/MM/yyyy}")
As it says in Stephen's answer, you have to make your formats match between the tags in your model to what is shown in the View, and it should be of the yyyy-MM-dd (ISO) format, regardless of how you actually want to display the date:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
// .... your namespace .... your class....
[DisplayName("Year Bought")]
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
And he's right, because we have [DataType(DataType.Date)], we don't need #type = date in our HtmlAttributes on the View.
Where my answer differs from his is how to actually apply the value from the Model to the control on the View. Since YearBought is a Nullable<DateTime>, we have to set it with its value a certain way, using .Value:
#Html.EditorFor(model => model.YearBought,
new { htmlAttributes = new { #class = "form-control datepicker",
#Value = Model.YearBought.Value.Date.ToString("yyyy-MM-dd") } })
Paying close attention to set the .ToString("yyyy-MM-dd"). It's not going to display in the box like that, though - at least for me - probably because my U.S. Regional settings on my computer take over and display it as MM/dd/yyyy regardless. This might confuse some, but it's better to just "do" and not worry about it.
If YearBought was just a straight DateTime instead of a DateTime?, it would be without the .Value:
#Html.EditorFor(model => model.YearBought,
new { htmlAttributes = new { #class = "form-control datepicker",
#Value = Model.YearBought != null ?
Model.YearBought.Value.Date.ToString("yyyy-MM-dd") : null } })
I would make your view model's YearBought property a String for the easiest manipulation. The server can format the date, it can do the parsing on postback, and you can still use the DataType.Date data annotation for jQuery validation. This also ensures that the display value will be exactly what you want prior to being submitted to the view.
Alternative to the HTML type attribute, you can use an EditorTemplate in MVC to put the markup, CSS, and JS needed to render a custom editor for a known C# datatype like DateTime.
Here is a walkthrough for creating a custom 'EditorTemplate' in MVC (although not for a Date data type, but concept is the same)

dbcontext.savechanges always saves default Value

I have a SQL-Azure database created with Entity Framework 6.1, Code-First.
The "datetime" field in my 'EmazeEvents' table was created like this:
datetime = c.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()")
and defined like this in the code:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Index]
public DateTime datetime { get; set; }
I understand this means that in case this field is omitted in insertion, it will get by default the insertion date, which indeed it does.
However, I am having trouble inserting rows that set this field. Although I set the value of the appropriate variable, it still writes to the database the default date.
Some code extractions:
EmazeEvents is defined like this:
public class EmazeEvents:DbContext
{
public EmazeEvents()
: base("EmazeEvent")
{ }
public DbSet<EmazeEvent> events { get; set; }
}
}
What I do is:
context = new EmazeEvents();
EmazeEvent e = new EmazeEvent();
// e.datetime does get the correct date
e.datetime = DateTime.ParseExact("2014-05-31T00:00:06.8900000", "O", CultureInfo.InvariantCulture);
context.events.Add(e);
context.SaveChanges();
The record written to the database has the current date-time, ignoring the one in e.datetime.
I found out that the problem was with the definition of the 'datetime' field. When I removed the:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
It started letting me write other values than the default.

MVC 4 DropDownListFor is not populating the select list with the value in the Model

I am experiencing inconsistent issues with ASP.Net MVC4's implementation of DropDownListFor.
In my ViewModel I have two string properties Title and EmploymentStatus which have data annotations to validate the model. When the ModelState.IsValid is false and the user is sent back to my input form the Title drop down list defaults to the first item in the list and not the value tied to the ViewModel. However, the EmploymentStatus drop down is behaving as expected, and I can't easily see the difference.
My ViewModel contains the following properties:
[Display(Name = "Title")]
[RegularExpression("^omitted$", ErrorMessage="Please enter a title")]
public String Title
{
get;
set;
}
[Display(Name = "Employment status?")]
[RegularExpression("^omitted$", ErrorMessage = "Please enter your employment status")]
public String EmploymentStatus
{
get;
set;
}
My View contains the following two lines to render the drop down lists:
#Html.DropDownListFor(m => m.Title, new SelectList(LookupService.GetTitleLookup(),"Key","Value", Model.Title)
#Html.DropDownListFor(m => m.EmploymentStatus, new SelectList(LookupService.GetEmploymentStatusLookup(),"Key","Value", Model.EmploymentStatus))
The LookupService methods both return an object of Dictionary:
e.g.
"Mr", "Mr"
"Mrs", "Mrs"
etc
"F", "Full Time"
"P", "Part Time"
etc
As part of the SelectList constructor it allows you to set the SelectedValue (in my case Model.Title) which when debugging I have stepped through and confirmed that the Model value was valid.
There are many people who seem to having issues with DropDownListFor not displaying the selectedValue and it appears that occasionally the internal implementation uses the default value rather than the selected value passed in, and that it doesn't support indexed properties, neither seem to be applicable in my case.
Any help would be greatly appreciated.
Thanks
Just spent 5 hours trying to work out why it was happening to me and the answer lies with the name of the item you're calling the dropdown list for, namely 'Title' which I'll bet you're also setting on the ViewBag for the page title
ie.
#{
Viewbag.Title="My Page Title"
}
to prove the point, add a property on Viewbag called 'EmploymentStatus' and you'll find that stops working.

DateTime Formatting in MVC4 - DisplayTemplates

Im using MVC4 and have a lot of properties on my model that are of type DateTime?.
I thought that I could create a DisplayTemplate (inside Shared\DisplayTemplates) that will format my date as I wish.
However this does not work. It does not output the date in the specified format. Any help would be appreciated..
Model:
[Display(Name = "Date Submitted")]
[DataType(DataType.DateTime)]
public DateTime? DateSubmitted { get; set; }'
View:
#Html.DisplayFor(m => m.DateSubmitted)
Display Template:
DateTime?:
#model DateTime?
#string.Format("{0:yyyy-MM-dd}", Model)
Got it!!!
if you notice that in my property I have
[DataType(DataType.DateTime)]
where as it should be :
[DataType(DataType.Date)]
Doh!!!
Thanks for the help.
Use the DisplayFormat attribute:
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
Try write it as follows:
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
You can learn more info about this from here(on example section)
or if you wish to do this in view you can write it as follow in MVC4
#Html.TextBoxFor(x => x.DatePurchase, "{0:yyyy-MM-dd}")
and link