How to change date in editor in MVC? - asp.net-mvc

I have in model DateTime
public System.DateTime date_in { get; set; }
And this is its View:
<div class="form-group">
#Html.LabelFor(model => model.date_in, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.date_in, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.date_in, "", new { #class = "text-danger" })
</div>
</div>
when I just click the EditorFor() to change the date, It writes:
The field date_in must be a date.
all formats I tried to insert (with time and without and change the places of month and day) were wrong.
The individual way I
succeeded is when month value and day value smaller than 13
I have tried answers people answered on similar questions
like add globalization tag and custom binder
but nothing helped me.

Related

Recovery datetime value in the edit view

When i click in the edit view the datetime lost the value.
enter image description here
<div class="form-group">
#Html.LabelFor(model => model.DataNascimento, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DataNascimento, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.DataNascimento, "", new { #class = "text-danger" })
</div>
</div>
I would like, when i click in the edit view the value of DataNascimento recive the value from the database.
I hope you guys can help me.
You must force the control to display to dd/mm/yyyy formatted date. to do this you need to format the date.decorate the date property in model as below
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public System.DateTime DataNascimento{ get; set; }
If you are using MVC5,this should work
#Html.EditorFor(model => model.DataNascimento, new {htmlAttributes = new {#Value = #Model.DataNascimento.ToString("dd-MM-yyyy") } })

Edit user removes password - ASP.NET MVC

I am trying to edit the data for one of my users. However, whenever I edit something, the passwords which are hidden, are also being changed and apparently set to null, which render the user unable to log in next time he wants to login. I know that I might have been able to solve the issue by using ViewModels, but im trying to do it without.
Model
public class User : IdentityUser
{
[Display(Name = "First name")]
public String FirstName { get; set; }
[Display(Name = "Last name")]
public string LastName { get; set; }
public string Email{ get; set; }
}
Please notice that the User-class extends from IdentityUser which holds password variables.
Edit in Controller
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "FirstName,LastName,Email,PhoneNumber")] User user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
View for Edit
<div class="form-horizontal">
<h4>User</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PhoneNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PhoneNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PhoneNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
}
It is my understand that the Bind-parameter in the Edit-method either whitelist or blacklist the variables for editing. So for that reason i removed all of the values that shouldnt be edited by the user in Bind.
There are a couple of problems here. First, don't present these fields to the user in the first place. I can't imagine a reason why a user should be able to edit their "locked out" status, or their hashed password. Only include in the UI the fields which the user should actually be modifying. Hell, even this has horrible idea written all over it:
#Html.HiddenFor(model => model.Id)
You're not only allowing the user to edit everything about their user record, but you're also allowing them to specify another user record to edit. So any user in the system can completely edit any other user in the system.
Hopefully you see how this is a bad thing :)
Now, you can (and often must) include the identifier in a hidden field. The above problem is mainly bad because of what else you're doing:
db.Entry(user).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
You are completely and implicitly trusting whatever the user sends you to be a whole, correct, and complete record for the database. And replacing whatever existing record is there with whatever the user sends you. That's... not good.
This approach can work for some models, but certainly not sensitive ones like user security data.
Instead, fetch the existing record and only edit the necessary fields. Something like this:
var existingUser = db.Users.Single(u => u.Id == currentUserId);
existingUser.FirstName = user.FirstName;
existingUser.LastName = user.LastName;
// etc.
db.SaveChanges();
Notice that I used an otherwise undefined variable called currentUserId. Do not use model.Id, because again that's allowing the user to specify which other user they want to edit. Determing the current user ID by their current logged in session, not by what they send in the form. However you currently identify your users. (User.Identity?)
In short...
Only let the user see/edit what they're allowed to
Validate in the save action that the user is allowed to edit that data (never assume that they must be allowed to simply because they previously opened the page)
Only update the values meant to be updated in that operation, don't just wholesale replace an entire record of sensitive data

Asp.net mvc 5 cross browser date picker and time picker

I programming in mvc5 and i have problem.
My model:
[DataType(DataType.Date)]
[Required(ErrorMessage = "Required")]
public System.DateTime Date { get; set; }
[DataType(DataType.Time)]
[Required(ErrorMessage = "Required")]
public System.DateTime Time { get; set; }
View:
<div class="form-group">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Time, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Time, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Time, "", new { #class = "text-danger" })
</div>
</div>
When I use Google chrome date picker and time picker displays correctly, but when I use mozilla firefox this is only a textbox.
How i can to generalize it? I want always to have date picker and time picker.
The default editor template uses the html input type 'date', which is probably not supported in firefox. We created a custom editor template which falls back to jquery date picker (choose whatever js date picker, there are lots) if the browser does not support the date input type.
You can test this feature using modernizr if you want.

ASP.NET MVC 5 Scaffolding not creating elements for enum property

This is probably a newbie question, as I'm quite new to ASP.NET MVC 5. When I tell Visual Studio to add a View based on my ViewModel class, it completely skips properties defined like public EnumName? PropertyName { get; set; } and does not create any #Html.EditorFor calls for it.
However, if I manually add the call #Html.EditorFor(model => model.PropertyName, new { htmlAttributes = new { #class = "form-control" } }) I get exactly what I expect -- a dropdown which is empty by default. Should scaffolding not do this by itself?
My understanding is that this is supposed to be supported in the current version of ASP.NET MVC. Am I wrong about that, or am I missing something? Help or advice is greatly appreciated.
Thanks in advance!
These are the ASP.NET products installed:
ASP.NET and Web Tools 12.4.51016.0
ASP.NET Web Frameworks and Tools 2012.2 4.1.21001.0
ASP.NET Web Frameworks and Tools 2013 5.2.21010.0
Edit for sample code:
Here is a small section of the view model. There are 170 different properties, almost all of them nullable-Enum type.
public partial class MedicalHistoryViewModel
{
public YesNo? Cancer { get; set; }
public MedicalHistoryDiagnosed? CancerDiagnosed { get; set; }
public YesNoUnsure? CancerIndustrialInOrigin { get; set; }
public YesNo? Diabetes { get; set; }
public MedicalHistoryDiagnosed? DiabetesDiagnosed { get; set; }
public YesNoUnsure? DiabetesIndustrialInOrigin { get; set; }
public YesNo? HeartDisease { get; set; }
//...
[Display(Name = #"Do you attribute the sleep disturbance to pain, anxiety and/or depression, or to other factors?")]
[DataType(DataType.MultilineText)]
public string SleepDisturbanceAttributedToComments { get; set; }
[Display(Name = #"Other (please specify)")]
[DataType(DataType.MultilineText)]
public string ParentsGrandparentsMedicalHistoryComments { get; set; }
}
Here is the complete output I get from Scaffolding. As you can see, it has completely ignored all enum properties.
#model QmeSurveyApp.ViewModels.MedicalHistoryViewModel
#{
ViewBag.Title = "EditMedicalHistory"; }
<h2>EditMedicalHistory</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>MedicalHistoryViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.SleepDisturbanceAttributedToComments, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SleepDisturbanceAttributedToComments, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SleepDisturbanceAttributedToComments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SiblingsCousinsMedicalHistoryComments, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SiblingsCousinsMedicalHistoryComments, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SiblingsCousinsMedicalHistoryComments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ParentsGrandparentsMedicalHistoryComments, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ParentsGrandparentsMedicalHistoryComments, new { htmlAttributes
= new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ParentsGrandparentsMedicalHistoryComments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div> }
<div>
#Html.ActionLink("Back to List", "Index") </div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval") }
But, if I add this block manually, I get exactly what I want: a drop-down which is empty by default, with my full pick list as the choices.
<div class="form-group">
#Html.LabelFor(model => model.Cancer, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Cancer, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Cancer, "", new { #class = "text-danger" })
</div>
</div>
You don't mention it, but I'm guessing you're not using Entity Framework.
I had a similar situation in an MVC project I was working in without EF. I had a POCO with a property that was an enum, and it was being completely skipped by the scaffolding engine. I even tried overriding the T4 templates with my own CodeTemplates and that's when I noticed the ModelMetadata.Properties collection didn't even contain my enum property.
I finally got it to work just by adding an empty Code First Entity Data model to the project. Doing that adds the Data context class textbox to the Add View scaffold item, and the resulting scaffolded view now includes my enum properties. This seems like a bug to me.

Displaying [Date] Value in EditorFor: No overload method for 'ToString' takes 1 argument?

In my INV_Assets Model I have the following Date fields defined:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime? acquired_date { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime? disposed_date { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime created_date { get; set; }
Then on my Edit() view I have the following form-group's defined for each of these Date values:
<div class="form-group">
#*#Html.LabelFor(model => model.acquired_date, htmlAttributes: new { #class = "control-label col-md-2" })*#
<span class="control-label col-md-2">Acquired Date:</span>
<div class="col-md-10">
#Html.EditorFor(model => model.acquired_date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.acquired_date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#*#Html.LabelFor(model => model.disposed_date, htmlAttributes: new { #class = "control-label col-md-2" })*#
<span class="control-label col-md-2">Disposed Date:</span>
<div class="col-md-10">
#Html.EditorFor(model => model.disposed_date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.disposed_date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#*#Html.LabelFor(model => model.created_date, htmlAttributes: new { #class = "control-label col-md-2" })*#
<span class="control-label col-md-2">Created Date:</span>
<div class="col-md-10">
#Html.EditorFor(model => model.created_date, new { htmlAttributes = new { #class = "form-control", #Value = Model.created_date.ToString("yyyy-MM-dd") } })
#Html.ValidationMessageFor(model => model.created_date, "", new { #class = "text-danger" })
</div>
</div>
Now then, when created_date has a value, I can open the form and the EditorFor will properly display the value. However, the EditorFor()'s for acquired_date and disposed_date always show up as mm/dd/yyyy even if there is a value saved in the Database -- if the form is saved while the editor still shows mm/dd/yyyy the value in database changes to null.
When I try to specify acquired_date and disposed_date with (Ex.) #Value = Model.disposed_date.ToString("yyyy-MM-dd") for an htmlAttribute, both Model.acquired_date.ToString("yyyy-MM-dd") and Model.disposed_date.ToString("yyyy-MM-dd") flag as No overload method for 'ToString' takes 1 argument...?
Can anyone see what I am doing wrong?
Ideally I want to save the entered values with whatever Date the user specifies in the EditorFor and with the current Time at the moment of save. I then would like to display the value in format mm/dd/yyyy within the EditorFor if the user is viewing the record.
You've got a few things going here. First, I'd assume that EditorFor is generating an input with type of date. For the HTML5 date input type, the provided value must be in ISO format (YYYY-MM-DD). If it's not in this format, then it's treated as if you provided no value. On post, this is then saved to your database, resulting in the null values. Long and short, you need to change your display format to:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyInEditMode = true)]
This is where view models come in handy, as you can have this set on the a class used for editing the object and your true desired display format set on a class used to view the object.
Second, your date properties are nullables. So you can't call ToString with a format directly off them. Instead, you have to do something like:
#Model.disposed_date.Value.ToString("MM/dd/yyyy")
However, that will fail if the value is null, so you always need to make sure you have a value first by either wrapping it in an if block:
#if (Model.disposed_date.HasValue)
{
...
}
Or using a ternary:
#(Model.disposed_date.HasValue ? Model.disposed_date.Value.ToString("MM/dd/yyyy") : string.Empty)
The format needs to be [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] (ISO format)

Resources