I have gone through my code several times and still cannot figure what I might be doing wrong.
In my ASP.NET MVC Application, I want to be able to create a new user after a form has being submitted through the View Model. Part of the information submitted through the view model will be used to Populate the ApplicationUser Model.
Here is my View Model
[Column(TypeName = "decimal(18,2)")]
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "LoanAmount", ResourceType = typeof(Resources))]
public decimal LoanAmount { get; set; }
[Display(Name = "LoanPurpose", ResourceType = typeof(Resources))]
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
public LoanPurpose LoanPurpose { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "FirstName", ResourceType = typeof(Resources))]
public string FirstName { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "LastName", ResourceType = typeof(Resources))]
public string LastName { get; set; }
[Display(Name = "DateOfBirth", ResourceType = typeof(Resources))]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
public DateTime? DateOfBirth { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "StreetAddress", ResourceType = typeof(Resources))]
public string Street { get; set; }
[MaxLength(15)]
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "City", ResourceType = typeof(Resources))]
public string City { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "State", ResourceType = typeof(Resources))]
public string State { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "ZIP", ResourceType = typeof(Resources))]
public string ZipCode { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "Country", ResourceType = typeof(Resources))]
public string Country { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "Phone", ResourceType = typeof(Resources))]
public string Phone { get; set; }
[Column(TypeName = "decimal(18,2)")]
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "MonthlyHousingPayment", ResourceType = typeof(Resources))]
public decimal MonthlyHousingPayment { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[Display(Name = "EmploymentStatus", ResourceType = typeof(Resources))]
public EmploymentStatus EmploymentStatus { get; set; }
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "IndividualYearlyIncome", ResourceType = typeof(Resources))]
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
public decimal IndividualYearlyIncome { get; set; }
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "AdditionalYearlyIncome", ResourceType = typeof(Resources))]
public decimal? AdditionalYearlyIncome { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[EmailAddress(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "EmailInvalid")]
[Display(Name = "Email", ResourceType = typeof(Resources))]
public string Email { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[DataType(DataType.Password)]
[StringLength(100, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "StringLength", MinimumLength = 4)]
[Display(Name = "Password", ResourceType = typeof(Resources))]
public string Password { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
[StringLength(20, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "StringLength", MinimumLength = 4)]
[Display(Name = "Username", ResourceType = typeof(Resources))]
public string UserName { get; set; }
[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "PropertyValueRequired")]
public bool AcceptCreditReportTerms { get; set; }
public Guid ApplicationUserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
Here is my Controller (CheckRateController)
// POST: CheckRate/Index
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Index(CheckYourRateViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
FirstName = model.FirstName,
LastName = model.LastName,
UserName = model.UserName,
PhoneNumber = model.Phone,
DateOfBirth = model.DateOfBirth,
State = model.State,
Street = model.Street,
City = model.City,
Country = model.Country
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
// Add registered users to Customer role
await _userManager.AddToRoleAsync(user.Id, "Customer");
}
var loanApplication = new Loan
{
LoanPurpose = model.LoanPurpose,
LoanAmount = model.LoanAmount,
EmploymentStatus = model.EmploymentStatus,
MonthlyHousingPayment = model.MonthlyHousingPayment,
IndividualYearlyIncome = model.IndividualYearlyIncome,
AdditionalYearlyIncome = model.AdditionalYearlyIncome,
ApplicationUserId = Guid.Parse(user.Id)
};
db.Loans.Add(loanApplication);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
return View(model);
}
And this is How my View Starts (Index.cshtml)
<section class="main-chkout">
<div class="container">
#using (Html.BeginForm("Index", "CheckRate", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<h1>#Resources.CheckYourRate</h1>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="frm-bx">
<h2>How much would you like to borrow?</h2>
<div class="frm-gap">
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.LoanAmount)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty lgap">
#Html.TextBoxFor(m => m.LoanAmount, new { placeholder = #Resources.LoanAmount })
<span>$</span>
</div>
#Html.ValidationMessageFor(model => model.LoanAmount, "", new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.LoanPurpose)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty">
#Html.EnumDropDownListFor(model => model.LoanPurpose)
<i class="fa fa-caret-down" aria-hidden="true"></i>
</div>
#Html.ValidationMessageFor(model => model.LoanPurpose, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div> <!-- Form tab End -->
<div class="frm-bx">
<h2>Tell Us About Yourself</h2>
<div class="frm-gap">
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
<label for="">Full Name</label>
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="row">
<div class="col-md-6">
<div class="inp-sty">
#Html.TextBoxFor(m => m.FirstName, new { placeholder = #Resources.FirstName })
</div>
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
<div class="col-md-6">
<div class="inp-sty">
#Html.TextBoxFor(m => m.LastName, new { placeholder = #Resources.LastName })
</div>
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.DateOfBirth)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty">
#Html.TextBoxFor(m => m.DateOfBirth, new { placeholder = "Date of Birth (MM/DD/YYYY)" })
</div>
#Html.ValidationMessageFor(model => model.DateOfBirth, "", new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.Street)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty">
#Html.TextBoxFor(m => m.Street, new { placeholder = #Resources.StreetAddress })
</div>
#Html.ValidationMessageFor(model => model.Street, "", new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
<label for="">City & State</label>
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="row">
<div class="col-md-6">
<div class="inp-sty">
#Html.TextBoxFor(m => m.City, new { placeholder = #Resources.City })
</div>
#Html.ValidationMessageFor(model => model.City, "", new { #class = "text-danger" })
</div>
<div class="col-md-6">
<div class="inp-sty">
<div class="inp-sty">
#Html.TextBoxFor(m => m.State, new { placeholder = #Resources.State })
</div>
#Html.ValidationMessageFor(model => model.State, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
<label for="">Zip & Phone</label>
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="row">
<div class="col-md-6">
<div class="inp-sty">
#Html.TextBoxFor(m => m.ZipCode, new { placeholder = #Resources.ZIP })
</div>
#Html.ValidationMessageFor(model => model.ZipCode, "", new { #class = "text-danger" })
</div>
<div class="col-md-6">
<div class="inp-sty">
#Html.TextBoxFor(m => m.Phone, new { placeholder = #Resources.PhoneNumber })
</div>
#Html.ValidationMessageFor(model => model.Phone, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div> <!-- Row End -->
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.MonthlyHousingPayment)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty">
#Html.TextBoxFor(m => m.MonthlyHousingPayment, new { placeholder = #Resources.MonthlyHousingPayment })
</div>
#Html.ValidationMessageFor(model => model.MonthlyHousingPayment, "", new { #class = "text-danger" })
</div>
</div> <!-- Row End Here -->
</div>
</div> <!-- Form tab End -->
<div class="frm-bx">
<h2>What is your income?</h2>
<div class="frm-gap">
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.EmploymentStatus)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty">
#Html.EnumDropDownListFor(model => model.EmploymentStatus)
<i class="fa fa-caret-down" aria-hidden="true"></i>
</div>
#Html.ValidationMessageFor(model => model.EmploymentStatus, "", new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.IndividualYearlyIncome)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty lgap">
#Html.TextBoxFor(m => m.IndividualYearlyIncome, new { placeholder = #Resources.IndividualYearlyIncome })
<span>$</span>
</div>
#Html.ValidationMessageFor(model => model.IndividualYearlyIncome, "", new { #class = "text-danger" })
</div>
</div> <!-- Row End Here -->
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.AdditionalYearlyIncome)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty lgap">
#Html.TextBoxFor(m => m.AdditionalYearlyIncome, new { placeholder = #Resources.AdditionalYearlyIncome })
<span>$</span>
</div>
#Html.ValidationMessageFor(model => model.AdditionalYearlyIncome, "", new { #class = "text-danger" })
</div>
</div> <!-- Row End Here -->
</div>
</div> <!-- Form tab End -->
<div class="frm-bx">
<h2>Save your information</h2>
<div class="frm-gap">
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.Email)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty">
#Html.TextBoxFor(m => m.Email, new { placeholder = #Resources.Email })
</div>
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.UserName)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty">
#Html.TextBoxFor(m => m.UserName, new { placeholder = #Resources.Username })
</div>
#Html.ValidationMessageFor(model => model.UserName, "", new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="inp-sty1">
#Html.LabelFor(m => m.Password)
</div>
</div>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="inp-sty">
#Html.PasswordFor(m => m.Password, new { placeholder = #Resources.Password })
</div>
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div> <!-- Form tab End -->
</div> <!-- col-md-8 End -->
<div class="col-md-4 col-sm-4 col-xs-12">
<div class="chklst">
<ul>
<li>
<img src="~/Content/assets/images/stopwatch.svg" alt="">
<p>Check your rate in<br> 5 minutes</p>
</li>
<li>
<img src="~/Content/assets/images/percent.svg" alt="">
<p>Get lower rates</p>
</li>
<li>
<img src="~/Content/assets/images/wallet.svg" alt="">
<p>Single monthly payments</p>
</li>
<li>
<img src="~/Content/assets/images/calendar2.svg" alt="">
<p>Fixed terms—3 or 5 years*</p>
</li>
</ul>
</div>
</div>
<div class="clear"></div>
<div class="chl-txt">
<p>The following documents contain important information, including your agreement to do business with<br> <span>Lendy</span> electronically. <span>By clicking the box below, you confirm that you agree by electronic signature to:</span></p>
</div>
<label class="checke">
the Credit Report Authorization, Terms of Use and Electronic Consent, Data Terms of Use & Prosper privacy policies.
#Html.CheckBoxFor(m => m.AcceptCreditReportTerms)
<span class="checkmark"></span>
</label>
#Html.ValidationMessageFor(model => model.AcceptCreditReportTerms, "", new { #class = "text-danger" })
<input type="submit" class="btncus" value="Check your rates" />
</div>
}
</div>
Try updating BeginForm to look something like this...
Html.BeginForm("Index", "Home", FormMethod.Post)
I have noticed that you are checking whether the model state is valid or not in the controller method using 'ModelState.IsValid' property with if condition and all your code inside that if condition.
Check by adding a breakpoint to this location to check whether your submitted form model is valid or not at this point if it's false then your data will not be saved according to your logic.
Another thing is to make sure while using 'ModelState.IsValid' is that you are not posting invalid data for the particular field like if you have added validation for a decimal field in your view model and in form you are using 'TextBoxFor' tag helper for that particular field which accepts any characters and same for other data types also so make sure you are posting right data to controller otherwise 'ModelState.IsValid' will be false.
Related
I have a page written using some fake data in my controller, to render some mock data in my view. Here is the code I have:
Model
Data View Model
[Required]
[Display(Name = "Is this a remix?")]
public bool IsRemix { get; set; }
[Required]
[Display(Name = "Does this song contain sample(s)?")]
public bool ContainsSample { get; set; }
I had this in my ViewModel
public bool IsRemix { get; set; }
public bool ContainsSample { get; set; }
Controller
model.Songs = songs;
model.SongTitle = "Darkside of the Moon";
model.AlternativeSongTitle = "Wish You Were Here";
model.DurationMinutes = 3;
model.DurationSeconds = 57;
model.IsRemix = true;
model.ContainsSample = false;
View
<div class="form-group">
<label class="control-label col-md-4 pull-left" for="SongTitle">Is a Remix</label>
<div class="col-md-8">
<div class="admin-form theme-primary">
<div class="radio-custom radio-primary mt10 mr10 pull-left">
#Html.RadioButtonFor(m => m.IsRemix, true, new { #class = "control-label col-md-4" })
<label for="IsRemixYes">Yes</label>
</div>
<div class="radio-custom radio-primary mt10 pull-left">
#Html.RadioButtonFor(m => m.IsRemix, true, new { #class = "control-label col-md-4" })
<label for="IsRemixNo">No</label>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-4 pull-left" for="SongTitle">Contains Sample</label>
<div class="col-md-8">
<div class="admin-form theme-primary">
<div class="radio-custom radio-primary mt10 mr10 pull-left">
#Html.RadioButtonFor(m => m.ContainsSample, true, new { #class = "control-label col-md-4" })
<label for="ContainsSampleYes">Yes</label>
</div>
<div class="radio-custom radio-primary mt10 pull-left">
#Html.RadioButtonFor(m => m.ContainsSample, true, new { #class = "control-label col-md-4" })
<label for="ContainsSampleNo">No</label>
</div>
</div>
</div>
</div>
I am unsure how to get the radio buttons to be pre-selected.
This question already has answers here:
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 4 years ago.
I have this ViewModel:
public class DepositViewModel
{
public DepositViewModel()
{
DepositDate = DateTime.Now;
CollectedReceipts = new List<DepositQuantityAmountViewModel>();
CancelledReceipts = new List<DepositQuantityAmountViewModel>();
}
[Display(Name = "Deposit #")]
public long DepositId { get; set; }
[Display(Name = "Deposit Type")]
public string DepositType { get; set; }
[Display(Name = "Cashier #")]
public int CashierId { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Deposit Date")]
[DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime DepositDate { get; set; }
[Display(Name = "Collected Receipts")]
public IList<DepositQuantityAmountViewModel> CollectedReceipts { get; set; }
[Display(Name= "Cancelled Receipts")]
public IList<DepositQuantityAmountViewModel> CancelledReceipts { get; set; }
[Display(Name = "Finance Reference")]
[MaxLength(2000)]
public string FinanceReference { get; set; }
[Display(Name = "Received Amount")]
[DisplayFormat(DataFormatString = "{0:N2}", ApplyFormatInEditMode = true)]
public decimal ReceivedAmount { get; set; }
[Display(Name = "Payment Modes")]
public IList<BDOs.PayMode> PaymentModes { get; set; }
}
public class DepositQuantityAmountViewModel
{
[Display(Name = "Description")]
public string Description { get; set; }
[Display(Name = "Category")]
public string Category { get; set; }
[Display(Name = "Count")]
public int Count { get; set; }
[Display(Name = "Total")]
[DisplayFormat(DataFormatString = "{0:N2}", ApplyFormatInEditMode = true)]
public decimal Amount { get; set; }
}
In my view, I have this setup:
<div class="row">
<div class="col-sm-2">
<div class="form-group">
<fieldset>
<legend>#Html.DisplayNameFor(m => m.PaymentModes)</legend>
<div class="col-sm-12">
<div class="row">
#foreach (var modelPaymentMode in Model.PaymentModes)
{
#Html.DisplayFor(m => modelPaymentMode, "_DepositPartPaymentModes")
}
</div>
</div>
</fieldset>
</div>
</div>
<div class="col-sm-5">
<div class="form-group">
<fieldset>
<legend>#Html.DisplayNameFor(m => m.CollectedReceipts)</legend>
#Html.DisplayFor(m => m.CollectedReceipts, "_DepositPartDetail")
</fieldset>
</div>
</div>
<div class="col-sm-5">
<div class="form-group">
<fieldset>
<legend>#Html.DisplayNameFor(m => m.CancelledReceipts)</legend>
#Html.DisplayFor(m => m.CancelledReceipts, "_DepositPartDetail")
</fieldset>
</div>
</div>
</div>
And here are the display templates:
_DepositPartPaymentModes.cshtml
#model DA.Services.IBS.Business.BDO.PayMode
<div class="form-group">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control", #readonly = "readonly" })
</div>
_DepositPartDetail.cshtml
#model IEnumerable<DA.Services.IBS.Web.FinancePortalFull.Models.DepositQuantityAmountViewModel>
#foreach (var countAmountPair in Model)
{
if (countAmountPair.Category == "TotalCollected" || countAmountPair.Category == "TotalCancelled")
{
<div class="col-sm-12">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(m => countAmountPair.Description, new { #class = "form-control", #readonly = "readonly" })
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(m => countAmountPair.Amount, "{0:N2}", new { #class = "form-control", type = "numeric", dir = "rtl", #readonly = "readonly" })
</div>
</div>
</div>
</div>
}
else
{
<div class="col-sm-12">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(m => countAmountPair.Count, "{0:N0}", new { #class = "form-control", type = "numeric", dir = "rtl", #readonly = "readonly" })
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(m => countAmountPair.Amount, "{0:N2}", new { #class = "form-control", type = "numeric", dir = "rtl", #readonly = "readonly" })
</div>
</div>
</div>
</div>
}
}
I have tried to bind each template separately looking at different guides. I cannot get the collections to be returned to postback as they are null. They display properly all three collections are null on submission.
What am I doing wrong?
Solution
Do not use ForEach Loops in views to iterate collections. Use For Loops.
The issue is in using foreach loops. When this is rendered in HTML, the input elements are not given names that will mean anything to the model binder when you post. You need to change these to for loops and the inputs will be rendered correctly.
You may also need to change your model so that the list is not null when the binder is trying to add to it.
Eg:
#for (int i = 0; i < Model.PaymentModes; i++)
{
#Html.DisplayFor(m => Model.PaymentModes[i], "_DepositPartPaymentModes")
}
Use for loop instead of foreach.
Element should be like this.
<input type="text" name="List[0].PropertyName" value="XYZ" />
change #model IEnumerable<DA.Services.IBS.Web.FinancePortalFull.Models.DepositQuantityAmountViewModel> to #model List<DA.Services.IBS.Web.FinancePortalFull.Models.DepositQuantityAmountViewModel>
_DepositPartDetail.cshtml
for (int i=0;i<Model.Count(); i++)
{
{
if (countAmountPair.Category == "TotalCollected" || countAmountPair.Category == "TotalCancelled")
{
<div class="col-sm-12">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(m => m[i].Description, new { #class = "form-control", #readonly = "readonly" })
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(m => m[i].Amount, "{0:N2}", new { #class = "form-control", type = "numeric", dir = "rtl", #readonly = "readonly" })
</div>
</div>
</div>
</div>
}
else
{
<div class="col-sm-12">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(m => m[i].Count, "{0:N0}", new { #class = "form-control", type = "numeric", dir = "rtl", #readonly = "readonly" })
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(m => m[i].Amount, "{0:N2}", new { #class = "form-control", type = "numeric", dir = "rtl", #readonly = "readonly" })
</div>
</div>
</div>
</div>
}
}
I'm trying to fill a string list in my viewmodel by the view, and then return to the same with the other fields the way the user has filled them, and that without having to pass all my model to the controler, Sending only my list.
My OS View Model
public class OsViewModel
{
[Key]
public int OSId { get; set; }
[Display(Name = "Código")]
[Required(ErrorMessage = "Informe o código da OS")]
public string CodigoOS { get; set; }
[Display(Name = "Descrição")]
[Required(ErrorMessage = "Informe o descrição da OS")]
public string Descricao { get; set; }
[Display(Name = "Natureza OS")]
[Range(1, int.MaxValue, ErrorMessage = "Selecione uma opção")]
[Required(ErrorMessage = "Informe a natureza da OS")]
public string Natureza { get; set; }
public int codigoNatureza { get; set; }
[Display(Name = "Req")]
[Required(ErrorMessage = "Informe o código de requisição da OS")]
public string CodigoReq { get; set; }
public DateTime? SLA { get; set; }
[Display(Name = "Prev. Ínicio")]
public DateTime? ProgInic { get; set; }
[Display(Name = "Prev. Fim")]
public DateTime? ProgFim { get; set; }
[Display(Name = "Ínicio Real")]
public DateTime? RealInic { get; set; }
[Display(Name = "Fim Real")]
public DateTime? RealFim { get; set; }
[Display(Name = "Dt Lançamento")]
[Required(ErrorMessage = "Informe a data de lançamento da OS.")]
public DateTime? DtLancamento { get; set; }
[Display(Name = "Dt Status")]
[Required(ErrorMessage = "Informe a data em que a OS foi cadastrada.")]
public DateTime? DtStatus { get; set; }
[Display(Name = "Horas Prev.")]
public string QtdHorasPrev { get; set; }
[Display(Name = "Horas Reais")]
public string QtdHorasRealizadas { get; set; }
[Display(Name = "VL. Mat")]
[Required(ErrorMessage = "Informe o valor Material da OS")]
public decimal? ValorMaterial { get; set; }
[Display(Name = "VL. Serv")]
[Required(ErrorMessage = "Informe o valor de Serviço da OS")]
public decimal? ValorServico { get; set; }
[Display(Name = "VL. Tot")]
public decimal? ValorTotal { get; set; }
[Display(Name = "Tot. Pen")]
public decimal? ValoeDependenciaFaturado { get; set; }
[Display(Name = "M. Faturado ?")]
public bool ValorMaterialFaturado { get; set; }
[Display(Name = "S. Faturado ?")]
public bool ValorServicoFaturado { get; set; }
[Display(Name = "VL. Tot Fat.")]
public decimal? ValorTotalFaturado { get; set; }
public int codigoStatus { get; set; }
[Display(Name = "Status OS")]
[Range(1, int.MaxValue, ErrorMessage = "Selecione uma opção")]
[Required(ErrorMessage = "Informe o Status da OS")]
public EnumStatusOS StatusDaOS { get; set; }
[Display(Name = "Técnicos")]
[Required(ErrorMessage = "A OS deve possuir pelo menos um Técnico.")]
public int[] chkTecnicos { get; set; }
public ICollection<SelectListItem> listaTecnicos { get; set; }
public ICollection<SelectListItem> StatusOS { get; set; }
public ICollection<SelectListItem> NaturezaOS { get; set; }
public virtual ICollection<TecnicoViewModel> Tecnicos { get; set; }
public virtual ICollection<InfoOsViewModel> Status { get; set; }
public virtual ICollection<ObservacoesOSViewModel> ObservacoesOS { get; set; }
public virtual List<string> Observacoes { get; set; }
}
The list what i want to pass to my controller is :
public virtual List<string> Observacoes { get; set; }
My controller:
[HttpPost]
public ActionResult IncluirObservacoes(IEnumerable<InclusoesOsViewModel> inclusoes)
{
OsViewModel os = new OsViewModel {
//get inclusoes items
};
//TempData["Message"] = new[] { Resources.altera_sucesso, "sucesso" };
return Json(new { success = true, responseText = "O cadastro foi realizado com sucesso" }, JsonRequestBehavior.AllowGet);
}
My view model who receive my ajax request items:
public class InclusoesOsViewModel
{
public string name { get; set; }
public int value { get; set; }
public DateTime data { get; set; }
public List<string> observacoes { get; set; }
}
And, my view:
#model ControleOS.Apresentacao.MVC.Areas.Admin.ViewModels.OS.OsViewModel
#{
ViewBag.Title = "Cadastrar";
Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml";
}
<div class="col-md-12">
<div class="card" style="padding-top: 10px;">
<div class="row m-0 form-group fg-float">
#using (Html.BeginForm("IncluirObservacoes", "Os", FormMethod.Post, new { id = "frmCadastrarOS" }))
{
#Html.AntiForgeryToken()
#Html.Partial("_CreateOrEdit", Model)
<div class="col-md-12">
<button type="submit" class="btn btn-primary waves-effect" style="float: right; text-transform: uppercase;">Salvar</button>
Retornar
</div>
}
</div>
</div>
</div>
#Model.Observacoes
<script>
$(document).ready(function () {
var listaTecnicos = [];
var listaObservacoes = [];
//$("#Salvar").click(function () {
// localStorage.removeItem("menus");
//});
$("#btn-modalTecnicos").click(function () {
$("#listaDeTecnicos").empty();
$("#modal_tecnicos").modal("show");
});
$("#btn-retornarTecnicos").click(function () {
$("#modal_tecnicos").modal("hide");
});
$("#btn-salvarTecnicos").click(function () {
$("#modal_tecnicos").modal("hide");
$.each(listaTecnicos, function (i) {
$("#listaDeTecnicos").append('<li data-filtertext="' + listaTecnicos[i] + '">' + listaTecnicos[i] + '</li>');
});
});
$(".checkTecnicos").click(function () {
if ($(this).prop('checked') == true) {
var tecnico = $(this).attr("data-valuetwo");
listaTecnicos.push(tecnico);
}
else {
var tecnico = $(this).attr("data-valuetwo");
listaTecnicos.pop(tecnico);
}
});
//Observacao
$("#btn-modalObservacoes").click(function () {
$("#listaDeObservacoes").empty();
$("#modal_observacoes").modal("show");
});
$("#btn-retornarObservacoes").click(function () {
$("#modal_observacoes").modal("hide");
});
$("#btn-salvarObservacoes").click(function () {
$("#modal_observacoes").modal("hide");
var observacao = $("#txt-incluirObservacao").val();
incluirObservacao(observacao);
});
function incluirObservacao(observacao) {
listaObservacoes.push(observacao);
$.each(listaObservacoes, function (i) {
$("#listaDeObservacoes").append('<li data-filtertext="' + listaObservacoes[i] + '">' + listaObservacoes[i] + '</li>');
});
#*#Model.Observacoes = #Newtonsoft.Json.JsonConvert.SerializeObject(listaObservacoes);*#
};
$("#frmCadastrarOS").submit(function (e) {
var postData = $("#frmCadastrarOS").serializeArray();
var model = #Html.Raw(#Newtonsoft.Json.JsonConvert.SerializeObject(Model));
$.ajax({
url: "#Url.Action("IncluirObservacoes", "OS")",
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(postData),
dataType: 'html',
success: function (data) {
console.log("sucesso");
$("#modal_observacoes").modal("hide");
location.reload();
},
error: function (data) {
console.log("erro");
}
});
e.preventDefault();
});
})
</script>
My partial view model, Who is responsible for sending the itens in my modals.
#model ControleOS.Apresentacao.MVC.Areas.Admin.ViewModels.OS.OsViewModel
#{
ViewBag.Title = "_CreateOrEdit";
//13890
}
<style>
.fg-float .fg-label {
color:#6B1F7C !important;
}
</style>
<div class="col-md-12">
<div class="col-md-12">
<fieldset class="col-md-12">
<legend>ORDEM DE SERVIÇO</legend>
<div class="row">
<div class="form-group fg-float col-md-1">
<div class="fg-line">
#Html.TextBoxFor(m => m.CodigoOS, new { #class = "form-control fg-input negrito", #maxlength = "6" })
#Html.LabelFor(m => m.CodigoOS, new { #class = "fg-label", #id = "text-label" })
</div>
#Html.ValidationMessageFor(m => m.CodigoOS, "", new { #class = "has-error text-danger" })
</div>
<div class="form-group fg-float col-md-1">
<div class="fg-line">
#Html.TextBoxFor(m => m.CodigoReq, new { #class = "form-control fg-input negrito", #maxlength = "6" })
#Html.LabelFor(m => m.CodigoReq, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.CodigoReq, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-3 form-group fg-float">
<div class="select">
#Html.DropDownListFor(p => p.codigoStatus, Model.StatusOS.Select(option => new SelectListItem
{
Text = option.Text,
Value = option.Value,
Selected = (Model != null) && (option.Value == Model.codigoStatus.ToString())
}), "Selecione o Satatus da OS", new { #id = "ddlStatusDaOS", #SortDirection = "ASC", #sort = "true", #class = "form-control roxo negrito" })
</div>
#Html.ValidationMessageFor(c => c.codigoStatus, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-3 form-group fg-float">
<div class="select">
#Html.DropDownListFor(p => p.codigoNatureza, Model.NaturezaOS.Select(option => new SelectListItem
{
Text = option.Text,
Value = option.Value,
Selected = (Model != null) && (option.Value == Model.codigoNatureza.ToString())
}), "Selecione a Natureza da OS", new { #id = "ddlNaturezaDaOS", #SortDirection = "ASC", #sort = "true", #class = "form-control roxo negrito" })
</div>
#Html.ValidationMessageFor(c => c.codigoNatureza, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-2 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.DtLancamento, new { #class = "form-control fg-input date negrito" })
#Html.LabelFor(m => m.DtLancamento, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.DtLancamento, "", new { #class = "has-error text-danger negrito" })
</div>
<div class="col-md-1 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.DtStatus, new { #class = "form-control fg-input date negrito" })
#Html.LabelFor(m => m.DtStatus, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.DtStatus, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-1 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.SLA, new { #class = "form-control fg-input date negrito", #id = "destaqueSLA" })
#Html.LabelFor(m => m.SLA, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.SLA, "", new { #class = "has-error text-danger" })
</div>
</div>
<div class="row m-t-10">
<div class="form-group fg-float col-md-12">
<div class="fg-line">
#Html.TextBoxFor(m => m.Descricao, new { #class = "form-control fg-input negrito" })
#Html.LabelFor(m => m.Descricao, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.Descricao, "", new { #class = "has-error text-danger " })
</div>
</div>
</fieldset>
</div>
<div class="col-md-12">
<fieldset class="col-md-12 m-t-20">
<legend>OBSERVAÇÕES</legend>
<div class="pmb-block">
<div class="pmbb-header">
<h4>
<i class="zmdi zmdi-collection-text m-r-5"></i>Observações
<i class="zmdi zmdi-plus"></i>
</h4>
</div>
<div class="pmbb-body p-l-30">
<div class="pmbb-view">
<ul data-role="listview" data-filter="true" id="listaDeObservacoes"></ul>
</div>
</div>
</div>
</fieldset>
</div>
<div class="col-md-12">
<fieldset class="col-md-6 m-t-20">
<legend>PROGRAMAÇÃO</legend>
<div class="row">
<div class="col-md-4 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.ProgInic, new { #class = "form-control fg-input date" })
#Html.LabelFor(m => m.ProgInic, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.ProgInic, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-4 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.ProgFim, new { #class = "form-control fg-input date" })
#Html.LabelFor(m => m.ProgFim, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.ProgFim, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-4 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.QtdHorasPrev, new { #class = "form-control fg-input" })
#Html.LabelFor(m => m.QtdHorasPrev, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.QtdHorasPrev, "", new { #class = "has-error text-danger" })
</div>
</div>
</fieldset>
<fieldset class="col-md-6 m-t-20">
<legend>REALIZAÇÃO</legend>
<div class="row">
<div class="col-md-4 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.RealInic, new { #class = "form-control fg-input date" })
#Html.LabelFor(m => m.RealInic, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.RealInic, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-4 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.RealFim, new { #class = "form-control fg-input date" })
#Html.LabelFor(m => m.RealFim, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.RealFim, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-4 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.QtdHorasRealizadas, new { #class = "form-control fg-input" })
#Html.LabelFor(m => m.QtdHorasRealizadas, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.QtdHorasRealizadas, "", new { #class = "has-error text-danger" })
</div>
</div>
</fieldset>
</div>
<div class="col-md-12">
<fieldset class="col-md-12 m-t-20">
<legend>TÉCNICOS</legend>
<div class="pmb-block">
<div class="pmbb-header">
<h4>
<i class="zmdi zmdi-wrench m-r-5"></i>Técnicos
<i class="zmdi zmdi-plus"></i>
</h4>
</div>
<div class="pmbb-body p-l-30">
<div class="pmbb-view">
<ul data-role="listview" data-filter="true" id="listaDeTecnicos"></ul>
</div>
</div>
</div>
</fieldset>
</div>
<div class="col-md-12">
<fieldset class="col-md-12 m-t-20 m-b-20">
<legend>ORÇAMENTO</legend>
<div class="row">
<div class="col-md-1 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.ValorMaterial, new { #class = "form-control fg-input money2" })
#Html.LabelFor(m => m.ValorMaterial, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.ValorMaterial, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-1 form-group fg-float" style="margin-left:3%;">
<div class="fg-line">
#Html.TextBoxFor(m => m.ValorServico, new { #class = "form-control fg-input money2" })
#Html.LabelFor(m => m.ValorServico, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.ValorServico, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-3 form-group fg-float">
#Html.DropDownListFor(m => m.ValorServicoFaturado, new SelectList(
new[]
{
new { Value = "true", Text = "Serviço faturado" },
new { Value = "false", Text = "Serviço não faturado" },
},
"Value",
"Text",
Model
), new { #id = "", #SortDirection = "ASC", #sort = "true", #class = "form-control roxo" })
#Html.ValidationMessageFor(m => m.ValorServicoFaturado, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-3 form-group fg-float">
#Html.DropDownListFor(m => m.ValorMaterialFaturado, new SelectList(
new[]
{
new { Value = "true", Text = "Material faturado" },
new { Value = "false", Text = "Material não faturado" },
},
"Value",
"Text",
Model
), new { #id = "", #SortDirection = "ASC", #sort = "true", #class = "form-control roxo" })
#Html.ValidationMessageFor(m => m.ValorMaterialFaturado, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-1 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.ValorTotalFaturado, new { #class = "form-control fg-input money2" })
#Html.LabelFor(m => m.ValorTotalFaturado, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.ValorTotalFaturado, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-1 form-group fg-float" style="margin-left:2%;">
<div class="fg-line">
#Html.TextBoxFor(m => m.ValoeDependenciaFaturado, new { #class = "form-control fg-input money2" })
#Html.LabelFor(m => m.ValoeDependenciaFaturado, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.ValoeDependenciaFaturado, "", new { #class = "has-error text-danger" })
</div>
<div class="col-md-1 form-group fg-float">
<div class="fg-line">
#Html.TextBoxFor(m => m.ValorTotal, new { #class = "form-control fg-input money2" })
#Html.LabelFor(m => m.ValorTotal, new { #class = "fg-label" })
</div>
#Html.ValidationMessageFor(m => m.ValorTotal, "", new { #class = "has-error text-danger" })
</div>
</div>
</fieldset>
</div>
</div>
<div class="modal fade" id="modal_tecnicos" data-backdrop="static" data-keyboard="false" tabindex="-1" role="dialog" aria-hidden="true" align="center">
<div class="modal-dialog">
<div class="modal-content" style="width:auto;">
<div class="modal-header" align="center" style="margin-bottom: -20px;">
<h4 class="modal-title"><i class="zmdi zmdi-wrench m-r-5"></i> Selecione os técnicos abaixo</h4>
<hr style="margin-top:10px;" />
</div>
<div class="modal-body" align="center">
<div class="col-md-12">
<div class="col-md-12 m-b-15 z-depth-1">
<h4 style="border-bottom: 1px solid #673673;">Técnicos</h4>
#foreach (var tecnicos in Model.listaTecnicos)
{
<div class="col-md-6 checkbox" style="margin-top: 10px; text-align:center;">
<label id="chk-Tecnicos" class="pull-left">
<input type="checkbox" class="checkTecnicos" data-valuetwo="#tecnicos.Text" style="margin-left:-20px;" name="chkTecnicos" checked="#tecnicos.Selected" value="#tecnicos.Value">
<i class="input-helper" id="chkicon"></i>
#tecnicos.Text
</label>
</div>
}
</div>
#Html.ValidationMessageFor(d => d.chkTecnicos, "", new { #class = "has-error text-danger" })
</div>
</div>
<div class="modal-footer">
Retornar
Salvar
</div>
</div>
</div>
</div>
<div class="modal fade" id="modal_observacoes" data-backdrop="static" data-keyboard="false" tabindex="-1" role="dialog" aria-hidden="true" align="center">
<div class="modal-dialog">
<div class="modal-content" style="width:auto;">
<div class="modal-header" align="center" style="margin-bottom: -20px;">
<h4 class="modal-title"><i class="zmdi zmdi-collection-text m-r-5"></i>Incluir nova observação</h4>
<hr style="margin-top:10px;" />
</div>
<div class="modal-body" align="center">
<div class="col-md-12">
<div class="col-md-12 m-b-15 z-depth-1">
<h4 style="border-bottom: 1px solid #673673;">Observações</h4>
<div class="row m-t-10 m-t-20">
<div class="form-group fg-float col-md-12">
<div class="fg-line">
<div class="fg-line">
<input type="text" id="txt-incluirObservacao" class="form-control">
<label class="fg-label">Observação</label>
</div>
</div>
#Html.ValidationMessageFor(m => m.Descricao, "", new { #class = "has-error text-danger " })
</div>
</div>
</div>
#Html.ValidationMessageFor(d => d.Observacoes, "", new { #class = "has-error text-danger" })
</div>
</div>
<div class="modal-footer">
Retornar
Salvar
</div>
</div>
</div>
</div>
So how can I send to my controller as the user inserts into my list and return it filled in my view so that I can then send my OsViewModel in the form normally?
Basic, I want to pass my listaObservacoes[] to my #Model.Observacoes.
action method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterViewModel blahblah)
{
HttpPostedFileBase uploadFile;
if (ModelState.IsValid)
{
if (blahblah != null)
{
var obj = new tblPersonalDetail()
{
FirstName = blahblah.FirstName,
LastName = blahblah.LastName,
Title = blahblah.Title,
Address = blahblah.Address,
Suburb = blahblah.Suburb,
HomePhone = blahblah.HomePhone,
Mobile = blahblah.Mobile,
Email = blahblah.Email,
EmergencyName = blahblah.EmergencyContactName,
EmergencyPhone = blahblah.EmergencyContactPhone,
EmergencyEmail = blahblah.EmergencyContactEmail,
EmergencyRelation = blahblah.EmergencyContactRelation,
DrivingLicenceExpiryDate = blahblah.DrivingLicenceExpiryDate,
DrivingLicenceNo = blahblah.DrivingLicenceNo,
DateofBirth = blahblah.DateofBirth
};
//if (uploadFile != null && !string.IsNullOrEmpty(uploadFile.FileName))
//{
// uploadFile.SaveAs(Server.MapPath($#"~\Content\Images\{uploadFile.FileName}"));
// obj.ScannedImageLocation = ($#"~\Content\Images\{uploadFile.FileName}");
//}
db.tblPersonalDetails.Add(obj);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(blahblah);
}
--registerviewmodel
public class RegisterViewModel
{
public string Title;
public string FirstName;
public string LastName;
public string Address;
public string Suburb;
public string HomePhone;
public string Mobile;
public string Email;
public string EmergencyContactName;
public string EmergencyContactRelation;
public string EmergencyContactPhone;
public string EmergencyContactEmail;
public string DrivingLicenceNo;
// [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime DrivingLicenceExpiryDate;
public string DrivingLicenceImage;
// [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString ="{0:yyyy-MM-dd}")]
public DateTime DateofBirth;
public string Notes;
public string NextAppointment;
public string Name
{
get
{
return $"{FirstName} {LastName}";
}
}
}
the viewmodel on post is all null. if i use the tblPersonalDetail model class generated by the entityframework and then change the reference in the view (Register.cshtml), it posts with the data. However not with the custom view model.
--Register.cshtml
#model Leo.ViewModel.RegisterViewModel
#{
ViewBag.Title = "Register New User";
}
#using (Html.BeginForm("Register", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-md-8">
<div class="panel">
<div class="panel-heading tabbable" tabindex="0"><h1>Personal Details</h1></div>
<div class="panel-body">
<div class="form-group row">
<div class="col-sm-6">
#Html.LabelFor(model => model.Title, "Title", htmlAttributes: new { #class = "control-label" })
<select class="form-control" id="Title">
<option>Mr</option>
<option>Mrs</option>
<option>Dr</option>
<option>Miss</option>
</select>
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
#Html.LabelFor(model => model.FirstName, "First Name", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-sm-6">
#Html.LabelFor(model => model.LastName, "Last Name", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
#Html.LabelFor(model => model.Address, "Address", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Address, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-sm-6">
#Html.LabelFor(model => model.Suburb, "Suburb", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Suburb, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
#Html.LabelFor(model => model.HomePhone, "Home Phone", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.HomePhone, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-sm-6">
#Html.LabelFor(model => model.Mobile, "Mobile", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Mobile, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
#Html.LabelFor(model => model.Email, "Email", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
<div class="panel-heading tabbable" tabindex="0"><h1>Emergency Details</h1></div>
<div class="panel-body">
<div class="form-group row">
<div class="col-sm-6">
#Html.LabelFor(model => model.EmergencyContactName, "Name", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.EmergencyContactName, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-sm-6">
#Html.LabelFor(model => model.EmergencyContactRelation, "Relation", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.EmergencyContactRelation, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
#Html.LabelFor(model => model.EmergencyContactPhone, "Phone", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.EmergencyContactPhone, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-sm-6">
#Html.LabelFor(model => model.EmergencyContactEmail, "Email", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.EmergencyContactEmail, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
<div class="panel-heading tabbable" tabindex="0"><h1>Driving Licence Details</h1></div>
<div class="panel-body">
<div class="form-group row">
<div class="col-sm-6">
#Html.LabelFor(model => model.DrivingLicenceNo, "Licence No", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.DrivingLicenceNo, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-sm-6">
#Html.LabelFor(model => model.DrivingLicenceExpiryDate, "Expiry Date", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.DrivingLicenceExpiryDate, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
#Html.LabelFor(model => model.DrivingLicenceImage, "Licence Image", htmlAttributes: new { #class = "control-label" })
<input type="file" name="uploadFile" />
</div>
<div class="col-sm-6">
#Html.LabelFor(model => model.DateofBirth, "Date of Birth", htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.DateofBirth, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
<input type="submit" class="btn btn-primary form-control" value="Submit" />
</div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">Notes</div>
<div class="panel-body">
<textarea rows="10" cols="15" class="form-control" id="Notes"></textarea>
</div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">Invoice</div>
<div class="panel-body">
<div class="form-group row">
<div class="col-sm-6">
<label for="Paid">Paid</label>
<input class="form-control" type="text" id="Paid" placeholder="Amount Paid">
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
<label for="Balance">Balance</label>
<input class="form-control" type="text" id="Balance" placeholder="Balance">
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
<label for="Total">Total</label>
<input class="form-control" type="text" id="Total" placeholder="Total Amount">
</div>
</div>
Print Invoice
</div>
</div>
</div>
</div>
}
You have fields not properties, you need to change your view model definition to have properties like:
public class RegisterViewModel
{
public string Title { get; set;}
public string FirstName { get; set;}
//............
//............
}
The default model binder in ASP.NET MVC will only bind to publicly accessible properties, however you are currently using fields, which will not be bound.
You'll just need to decorate them with the necessary getters / setters as seen below to make them into properties :
public class RegisterViewModel
{
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// Others omitted for brevity
}
I want to add input to form dynamically with jQuery templates.
My viewModel for rendering form is listed below
public class FormViewModel
{
public int Id { get; set; }
[Required]
[StringLength(25, ErrorMessage = "Max firstname length is 25 symbols.")]
[DisplayName("First name")]
public string FirstName { get; set; }
[Required]
[StringLength(25, ErrorMessage = "Max lastname length is 25 symbols.")]
[DisplayName("Last name")]
public string LastName { get; set; }
[Required]
[Email(ErrorMessage = "Provide correct email address, please.")]
[DisplayName("Email")]
public string Email { get; set; }
[Range(16, 150, ErrorMessage = "Age should be between 16 and 150.")]
[DisplayName("Age")]
public int? Age { get; set; }
public IList<DiscountCode> Discounts { get; set; }
}
This is my model which I use for inputs that will be created dynamically.
public class DiscountCode
{
[Required]
[DisplayName("Code name")]
[StringLength(10, ErrorMessage = "Max name length is 10 symbols.")]
public string Code { get; set; }
[Required]
[DisplayName("Code discount")]
[Integer(ErrorMessage = "The field Percent should be a positive non-decimal number")]
[Range(1,60, ErrorMessage = "The field Percent should be between 1 and 60.")]
public int Percent { get; set; }
}
I have this partial view for rendering DiscountCode inputs
#using DynamicForm.Models
#model FormViewModel
#if (Model != null && Model.Discounts != null)
{
for (int i = 0; i < Model.Discounts.Count; i++)
{
<div class="row">
<input type="hidden" name="Discounts.Index" value="#i" />
<div class="col-md-4 form-group">
<div class="input-group">
#Html.TextBoxFor(m => m.Discounts[i].Code, new { #class = "form-control " })
#Html.ValidationMessageFor(m => m.Discounts[i].Code, string.Empty, new { #class = "help-block" })
</div>
</div>
<div class="col-md-6 form-group">
<div class="input-group">
#Html.LabelFor(m => m.Discounts[i].Percent, new { #class = "control-label" })
#Html.TextBoxFor(m => m.Discounts[i].Percent, new { #class = "form-control " })
#Html.ValidationMessageFor(m => m.Discounts[i].Percent, string.Empty, new { #class = "help-block" })
</div>
</div>
<div class="col-md-2 form-group">
<div class="input-group">
<button type="button" class="btn btn-primary removeDiscountRow">Remove</button>
</div>
</div>
</div>
}
}
And for adding discount inputs I use this code snippet
var data = { index: lastIndex };
var html = $.templates("#discountRow").render(data);
$(html).appendTo($discountsContainer);
and this template
<script id="discountRow" type="text/x-jsrender">
<div class="row">
<input type="hidden" name="Discounts.Index" value="{{: index}}">
<div class="col-md-4 form-group">
<div class="input-group">
<label class="control-label" for="Discounts_{{: index}}__Code">Code name</label>
<input class="form-control " data-val="true" data-val-required="Code is required" data-val-length="Max name length is 10 symbols." data-val-length-max="10"
id="Discounts_{{: index}}__Code" name="Discounts[{{: index}}].Code" type="text" value="">
<span class="field-validation-valid help-block" data-valmsg-for="Discounts[{{: index}}].Code" data-valmsg-replace="true"></span>
</div>
</div>
<div class="col-md-6 form-group">
<div class="input-group">
<label class="control-label" for="Discounts_{{: index}}__Percent">Code discount</label>
<input class="form-control " data-val="true" data-val-required="Percent is required" data-val-number="The field Code discount must be a number."
data-val-range="The field Percent should be between 1 and 60." data-val-range-max="60" data-val-range-min="1"
data-val-regex="The field Percent should be a positive non-decimal number."
data-val-regex-pattern="^-?\d+$" data-val-required="The Code discount field is required."
id="Discounts_{{: index}}__Percent" name="Discounts[{{: index}}].Percent" type="text" value="0" aria-required="true" aria-invalid="false"
aria-describedby="Discounts_{{: index}}__Percent-error">
<span class="help-block field-validation-valid" data-valmsg-for="Discounts[{{: index}}].Percent" data-valmsg-replace="true"></span>
</div>
</div>
<div class="col-md-2 form-group">
<div class="input-group">
<button type="button" class="btn btn-primary removeDiscountRow">Remove</button>
</div>
</div>
</div>
</script>
As you can see I just copy output of razor and insert it in template. So if I change validation in model I'll change template each time. How to generate this template automatic with preserving all data attributes for client-side validation ?
You can generate templte code like you create your input code, but Model.Discounts must have at least one element. See code below. I add DiscountCode to discounts if its empty and change some html attributes to make template display as you want;)
if (Model.Discounts == null || Model.Discounts.Count <= 0)
{
Model.Discounts = new List<DiscountCode> { new DiscountCode() };
}
<script id="discountRow" type="text/x-jsrender">
<div class="row">
<input type="hidden" name="Discounts.Index" value="{{: index}}" />
<div class="col-md-4 form-group">
<div class="input-group">
#Html.LabelFor(m => m.Discounts[0].Percent, new { #class = "control-label", For = "Discounts[{{: index}}].Code" })
#Html.TextBoxFor(m => m.Discounts[0].Code, new { #class = "form-control ", Id = "Discounts_{{: index}}__Code", Name = "Discounts[{{: index}}].Code", Value="" } )
#Html.ValidationMessageFor(m => m.Discounts[0].Code, string.Empty, new { #class = "help-block", Data_Valmsg_For = "Discounts[{{: index}}].Code" })
</div>
</div>
<div class="col-md-6 form-group">
<div class="input-group">
#Html.LabelFor(m => m.Discounts[0].Percent, new { #class = "control-label", For = "Discounts[{{: index}}].Percent" })
#Html.TextBoxFor(m => m.Discounts[0].Percent, new { #class = "form-control ", Id = "Discounts_{{: index}}__Percent", Name = "Discounts[{{: index}}].Percent", Value = "" })
#Html.ValidationMessageFor(m => m.Discounts[0].Percent, string.Empty, new { #class = "help-block", Data_Valmsg_For = "Discounts[{{: index}}].Percent" })
</div>
</div>
<div class="col-md-2 form-group">
<div class="input-group">
<button type="button" class="btn btn-primary removeDiscountRow">Remove</button>
</div>
</div>
</div>
</script>