DataAnnotation and value by default - asp.net-mvc

I have a property in view model:
[Display(Name = "Date")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public System.DateTime DateTime { get; set; }
and view:
<div class="form-group">
#Html.LabelFor(model => model.DateTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DateTime, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.DateTime, "", new { #class = "text-danger" })
</div>
</div>
and page shows default value as 01/01/0001 on form:
I want have not any default value (user should specify correct value and can't send form without it). How to remove default value?

You have to make public System.DateTime DateTime { get; set; } a nullable DateTime.

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") } })

ASP.NET MVC Route Parameter replacing Model Field

I am testing an ASP.NET MVC 5 application with Visual Studio 2017 Community edition.
I am trying to save Assort model to database with following code.
I am navigating to Assort Create page with URL /Assort/Create/1A.
The parameter 1A is needed on create page of Assort as I need to display some additional information from that parameter on create page itself.
But when I submit the data, 1A parameter value is being inserted as ID value of Assort model, and thus my ModelState is invalid and I am unable to save data.
Can anyone help me?
MODEL
public class Assort
{
[Key]
public int ID { get; set; }
[Display(Name = "Assort No")]
[Required(ErrorMessage = "Assort No can not be empty.")]
public int ASSORTNO { get; set; }
[Display(Name = "Date")]
[Required(ErrorMessage = "Date can not be empty.")]
public DateTime DATE { get; set; }
[Display(Name = "RFNO")]
[Required(ErrorMessage = "RFNO can not be empty.")]
[StringLength(50)]
public string RFNO { get; set; }
[Display(Name = "Manager")]
[Required(ErrorMessage = "Manager can not be empty.")]
public int MANAGER { get; set; }
[Display(Name = "Caret")]
[Required(ErrorMessage = "Caret can not be empty.")]
public decimal CARET { get; set; }
[Display(Name = "MFG Size")]
[Required(ErrorMessage = "MFG Size can not be empty.")]
public decimal MFGSIZE { get; set; }
[Display(Name = "Total PCS")]
[Required(ErrorMessage = "Total PCS can not be empty.")]
public decimal TOTALPCS { get; set; }
[StringLength(50)]
public string APPROVALSTATUS { get; set; }
[Display(Name = "Details")]
public string DETAILS { get; set; }
[ScaffoldColumn(false)]
public DateTime CREATE_TIMESTAMP { get; set; }
[ScaffoldColumn(false)]
public DateTime LAST_EDIT_TIMESTAMP { get; set; }
[UIHint("AssortReturn")]
public virtual List<AssortReturn> AssortReturn { get; set; }
public Assort()
{
AssortReturn = new List<AssortReturnModel.AssortReturn>();
}
[ForeignKey("RFNO")]
public virtual Rough rough { get; set; }
}
ACTION
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Assort assort)
{
if (ModelState.IsValid)
{
assort.APPROVALSTATUS = "NOT APPROVED";
assort.CREATE_TIMESTAMP = DateTime.Now;
assort.LAST_EDIT_TIMESTAMP = DateTime.Now;
db.Assorts.Add(assort);
db.SaveChanges();
return RedirectToAction("Index");
}
Initialize(assort.RFNO,"CREATE");
return View(assort);
}
VIEW
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ASSORTNO, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ASSORTNO, new { htmlAttributes = new {#readonly="readonly",#Value=ViewBag.ASSORTNO, #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ASSORTNO, "", new { #class = "text-danger" })
</div>
</div>
<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 {#autofocus="autofocus",#Value=ViewBag.CURRENTDATE, #class = "form-control date" } })
#Html.ValidationMessageFor(model => model.DATE, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RFNO, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.RFNO, new { htmlAttributes = new { #readonly = "readonly", #Value = ViewBag.RFNO, #class = "form-control" } })
#Html.TextBox("AVAILABLECARET",(decimal)ViewBag.AVAILABLECARET,new {#class="form-control txtAvailablecaret",#readonly="readonly" })
#Html.ValidationMessageFor(model => model.RFNO, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MANAGER, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#*#Html.EditorFor(model => model.MANAGER, new { htmlAttributes = new { #class = "form-control" } })*#
#Html.DropDownListFor(model => model.MANAGER, new SelectList(ViewBag.MANAGERLIST, "ID", "USERNAME"), "Select Manager", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.MANAGER, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CARET, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CARET, new { htmlAttributes = new { #class = "form-control txtCaret" } })
#Html.ValidationMessageFor(model => model.CARET, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MFGSIZE, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MFGSIZE, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MFGSIZE, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TOTALPCS, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TOTALPCS, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TOTALPCS, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DETAILS, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DETAILS, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.DETAILS, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default btnCreate" />
</div>
</div>
</div>
}
This is because of the default route, which is handling your request. It looks like:
{controller}/{action}/{id}
And so A1 gets bound to ID. If you want a different behavior, say A1 is still a part of the URL, but binds to a different param, say "name", you need a new route for that:
routes.MapRoute(
name: "CreateAssort",
url: "Assort/Create/{name}",
defaults: new { controller = "Assort", action = "Create"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Now "name" will hold A1 and not ID. Notice how your custom route comes before the default one. This is important - routing picks the first route that matches the request.
What you can do is add a hidden input field named ID to your view.
When the form will be submitted, the value from this field will take precedence over the one from your route i.e. '1A' and the model would have ID as 0 if you don't set the hidden input's value.
I had same issue. But problem is when you creating an model.
You need to have two methods.
[HttpGet] // http://localhost/Assort/Create/1
public ActionResult Create(int Id)
{
ModelState.Remove(nameof(Id)); // this will remove binding
var assort = new Assort()
{
Id = 'whatever',
....
};
return View(assort);
}
[HttpPost] // http://localhost/Assort/Create/
public ActionResult Create(Models.Assort assort)
{
if (ModelState.IsValid)
{
assort.APPROVALSTATUS = "NOT APPROVED";
assort.CREATE_TIMESTAMP = DateTime.Now;
assort.LAST_EDIT_TIMESTAMP = DateTime.Now;
db.Assorts.Add(assort);
db.SaveChanges();
return RedirectToAction("Index");
}
Initialize(assort.RFNO,"CREATE");
return View(assort);
}
C# ASP MVC Route Model ID bug

ValidationMessage in MVC View not displaying

I have a custom date validation and I have done as explained in
this link. Below is my Model code:
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}",ApplyFormatInEditMode=true)]
[DisplayName("Sch.Start Date:")]
[DataType(DataType.Date)]
[ValidProjectDate(ErrorMessage="Project Start Date cannot be greater than Project End Date.")]
public DateTime? ProjectScheduleStartDate { get; set; }
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
[DisplayName("Sch.End Date:")]
[DataType(DataType.Date)]
[ValidProjectDate(ErrorMessage = "Project End Date cannot be less than or Equal to Current Date.")]
public DateTime? ProjectScheduleEndDate { get; set; }
`
Below is my code in View:
<div class="form-group">
#Html.LabelFor(model => model.ProjectScheduleStartDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProjectScheduleStartDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProjectScheduleStartDate, "*", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProjectScheduleEndDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProjectScheduleEndDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProjectScheduleEndDate, "*", new { #class = "text-danger" })
</div>
</div>
<hr/>
#Html.ValidationSummary(true, "Please correct below errors", new { #class = "text-danger" })
Below is my code in Controller:
if (ModelState.IsValid)
{
ProjectManager pm = new ProjectManager();
pm.AddProjects(prj);
ViewBag.Result = "Record Inserted Successfully.";
ModelState.Clear();
}
else
{
ModelState.AddModelError(string.Empty, "An Error has happened");
}
return View("AddNewProject");
Even though I tried to display the validation message as mentioned in the model class, I am getting only star images instead of the validation messages. However, the Error messsages specified inside the validation summary is getting displayed. But I want to display the messages in the model class. Any clue?
I removed the star symbol on the ValidationMessageFor in View. It started working.. May be helpful for someone.
Your attribute's ValidationResult does not have a key associated with a field, which prevents ValidationMessageFor from working.
I would suggest using implementing the IValidatable interface on your ViewModel instead of your custom data validation attribute, unless there are many places in your application where this type of validation is required.
You will notice that it provides the name of the property as the key to associate the error with the field:
public class TestViewModel : IValidatableObject
{
public DateTime? ProjectStartDate { get; set; }
public DateTime? ProjectEndDate { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (ProjectStartDate > ProjectEndDate)
yield return new ValidationResult("The Project Start Date cannot be after the Project End Date.", new List<string>() { nameof(ProjectStartDate) });
if (ProjectEndDate < DateTime.Now)
yield return new ValidationResult("Project End Date cannot be less than or Equal to Current Date.", new List<string>() { nameof(ProjectEndDate) });
}
}

I can not save date in MVC

I've this model which has a couple of columns and one of them is date, but on post I get nothing of date, only in case if I give it the value of DateTime.Now then it will save the current date but If had selected some other date in the datepicker it will not save that as it should, so How can I pass the date to the view model on post, I can pass all the date from dropdown and textboxes but date is no where to found. Here is the code
My view model
[Display(Name = "Requested Date")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
public DateTime? RequestDate { get; set; }
[Display(Name = "Job Number")]
public string JobNo { get; set; }
Here is the Post Create method code
if (ModelState.IsValid)
{
var model = new PECEquipmentRequest()
{
ProjectId = pecEquipmentRequest.ProjectId,
JobNo = pecEquipmentRequest.JobNo,
RequestDate = pecEquipmentRequest.RequestDate
};
db.PECEquipmentRequests.Add(model);
db.SaveChanges();
}
and here is the my razor syntax
<div class="form-group">
#Html.LabelFor(model => model.RequestDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.RequestDate, new { htmlAttributes = new { #Value = DateTime.Now,#class = "form-control datepicker" } })
#Html.ValidationMessageFor(model => model.RequestDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.JobNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.JobNo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.JobNo, "", new { #class = "text-danger" })
</div>
</div>
and here is the kendo date picker that I'm using
$(document).ready(function () {
$(".datepicker").kendoDatePicker();
});
You can parse the date to the required format in the server side.
DateTime.ParseExact(str, "yyyyMMddHHmmss", CultureInfo.InvariantCulture);

Access public virtual dropdown value

I have a dropdown list and a datefield. If there is one specific value selected from the dropdown, the datefield should be required.
To solve that, I tried to use the requiredIf sttribute from the FoolProof library.
But I don't know how to access the selected value in the Model.
Model
//This is the datefield
[RequiredIf(tabState == "discarded")]
[DataType(DataType.Date)]
[Display(Name = "date discarded")]
public Nullable<System.DateTime> datDiscarded { get; set; }
//This is the dropdown
public virtual tabState tabState { get; set; }
tabState in Controller
ViewBag.intIdeaStateID = new SelectList(db.tabState, "intStateID", "strState");
dropdown in View
<div class="form-group">
#Html.LabelFor(model => model.intIdeaStateID, "State", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("intIdeaStateID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.intIdeaStateID, "", new { #class = "text-danger" })
</div>
</div>
How can I check if the selected value from the dropdown is "discarded"?
Thanks for your help.

Resources