Error with expressive annotations requiredif validator - model-view-controller

This is my view
<div id="Domain">
<ul class="formlist">
<li class="width100">
<div class="form-check form-check-inline">
<label class="form-check-label">
#Html.RadioButtonFor(model => model.domain_flag, 1, new { #class = "form-check-input" }) <span>Yes</span>
</label>
</div>
<div class="form-check form-check-inline">
<label class="form-check-label">
#Html.RadioButtonFor(model => model.domain_flag, 0, new { #class = "form-check-input", #checked = "checked" }) <span>No</span>
</label>
</div>
</li>
</ul>
<ul class="formlist">
<li>
<div class="frm-marg-b">
<label class="label"><b>#Html.LabelFor(model => model.domain_renew_date)</b></label>
<div class="textbx">
<div class="input-group">
#Html.TextBoxFor(model => model.domain_renew_date, new { #type = "datetime", #class = "form-control" })
#Html.ValidationMessageFor(model => model.domain_renew_date, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="frm-marg-b">
<label class="label"><b>#Html.LabelFor(model => model.domain_vendor_id)</b></label>
<div class="textbx">
#Html.DropDownListFor(model => model.domain_vendor_id, Model.domain_Vendor, "Please Select")
#Html.ValidationMessageFor(model => model.domain_vendor_id, "", new { #class = "text-danger" })
</div>
</div>
</li>
<li>
<div class="frm-marg-b">
<label class="label"><b>#Html.LabelFor(model => model.domain_exp_date)</b></label>
<div class="textbx">
<div class="input-group">
#Html.TextBoxFor(model => model.domain_exp_date, new { #type = "datetime", #class = "form-control" })
#Html.ValidationMessageFor(model => model.domain_exp_date, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="frm-marg-b">
<label class="label"><b>#Html.LabelFor(model => model.domain_amt)</b></label>
<div class="textbx">
#Html.EditorFor(model => model.domain_amt, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.domain_amt, "", new { #class = "text-danger" })
</div>
</div>
</li>
<li class="width100">
<div class="frm-marg-b">
<label class="label"><b>#Html.LabelFor(model => model.domain_remarks)</b></label>
<div class="textbx3">
#Html.TextAreaFor(model => model.domain_remarks, new { htmlAttributes = new { #class = "form-control", #rows = 2 } })
#Html.ValidationMessageFor(model => model.domain_remarks, "", new { #class = "text-danger" })
</div>
</div>
</li>
</ul>
</div>
My model
public int? domain_flag { get; set; }
[Display(Name = "Date of Renewal")]
[DataType(DataType.Date)]
[RequiredIf("domain_flag==1",ErrorMessage ="Enter Renew Date")]
public DateTime? domain_renew_date { get; set; }
[Display(Name = "Date of Expiry")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:mm/dd/yy}", ApplyFormatInEditMode = true)]
[RequiredIf("domain_flag==1", ErrorMessage = "Enter Expiry Date")]
public DateTime? domain_exp_date { get; set; }
[Display(Name = "Vendor")]
[RequiredIf("domain_flag==1", ErrorMessage = "Please Select Vendor")]
public int? domain_vendor_id { get; set; }
[Display(Name = "Amount(Rs.)")]
[RequiredIf("domain_flag==1", ErrorMessage = "Enter Amount")]
[RegularExpression("^[0-9]+$", ErrorMessage = "Enter Numeric Values")]
public decimal? domain_amt { get; set; }
[Display(Name = "Comments")]
public string domain_remarks { get; set; }
Global.asax
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(RequiredIfAttribute), typeof(RequiredIfValidator));
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(AssertThatAttribute), typeof(AssertThatValidator));
In this as soon as I select the radio button the required if error messages are displayed before entering the values. The error messages should be displayed on click of submit button before posting to the server. Is this possible with expressive annotations nuget package?

Yes it's possible with ExpressiveAnnotations.
#jwaliszko mentioned it.
You have to set the configuation of ea like this at client-side:
<script>
ea.settings.dependencyTriggers = '';

Related

How to data list to model and model's data send with one post process from view to controller?

My model(dto);
public class DTOExample
{
#region Properties
[Required(ErrorMessage = "Required")]
[DataType(DataType.Text)]
[Display(Name = "Name")]
public string Name{ get; set; }
[Required(ErrorMessage = "Required")]
[StringLength(12, ErrorMessage = "{0} alanı en az {1}, en çok {2} karakter olabilir.", MinimumLength = 12)]
[DataType(DataType.Text)]
[Display(Name = "Last Name")]
public string LastName{ get; set; }
[Display(Name = "Send Information")]
public List<DTOSendInformations> ListSend { get; set; }
}
public class DTOSendInformations
{
[Display(Name = "AdressOne")]
[Required(ErrorMessage = "Zorunlu alan")]
[StringLength(50, ErrorMessage = "{0} min {2}, max {1}", MinimumLength = 1)]
[DataType(DataType.Text)]
public string AdressOne{ get; set; }
[Display(Name = "AdressTwo")]
[StringLength(11, ErrorMessage = "{0} min {2}, max {1} karakter olabilir.", MinimumLength = 10)]
[DataType(DataType.Text)]
public string AdressTwo{ get; set; }
}
My View (I have written the necessary parts)
<div class="row">
<div class="col-md-6">
<div class="row">
<div class="col-md-4">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-8">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col-md-6">
<div class="row">
<div class="col-md-4">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-8">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ParcaliAlisIzinGostergesi, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div><br />
//I have a table,for AdressOne and AdressTwo,I can enter data dynamically int he view
<table id="tableSendInformation" class="table" cellpadding="0" cellspacing="0">
<thead>
<tr>Send Information Detail</tr>
<tr>
<th style="width:150px">AdressOne</th>
<th style="width:250px">AdressTwo</th>
<th></th>
</tr>
</thead>
<tbody></tbody>
<tfoot>
#{
for (int i = 0; i < Model.ListSend.Count; i++)
{
<tr>
<td>
#Html.EditorFor(l => l.ListSend [i].AdressOne)
</td>
<td>
#Html.EditorFor(l => l.ListSend [i].AdressTwo)
</td>
</tr>
}
}
</tfoot>
</table>
//my buttons;
<div class="float-right"> // my button(for AdressOne and AdressTwo)
<div class="col-md-offset-8">
<input type="button" value="Add" class="btn btn-primary" name="Add" id="Add"/>
</div>
</div>
<div class="col-md-offset-8"> //my submit button
<input type="submit" value="Save" id="buttonSave" class="btn btn-primary" name="buttonSave" />
</div>
I want Name,LastName, AdressOne,AdressTwo(multiple records) data, when you click the button(submit buton=>buttonSave) all of this information send from view to controller(I want to submit at the same time).
I want to send both my data and list in the model with a single post.
How can I do that?

Single model and multiple views

I have a one model with Mymodel it contains the properties like name ,age,contact, phone,address,sortcode ,sysmcode like this and all these are required fields.
I have controller with name Home.
In HomeController i have action methods like
index
Contact(Mymodel model)
Code(Mymodel model)
I have navigate to the index page and provided the details and submitted ,it navigate to the Contact page.
while loading contact page it showing the validation error message.
Try this sample code for you reference. I tested and working fine.
Model Class :
public class Mymodel
{
[Required]
public string Name { get; set; }
[Required]
public string Age { get; set; }
[Required]
public string Contact { get; set; }
[Required]
public string Phone { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string Sortcode { get; set; }
[Required]
public string Sysmcode { get; set; }
}
Home Controller Actions :
public class HomeController : Controller
{
public ActionResult Index()
{
//assigned value for test purposes.
Mymodel tt = new Mymodel()
{
Name = "Dumm",
Age = "55",
Address = "test",
Contact = "46516",
Phone = "516566",
Sortcode = "sdad",
Sysmcode = "asdad"
};
return View(tt);
}
public ActionResult Contact(Mymodel model)
{
ViewBag.Message = "Your contact page.";
return View(model);
}
}
And finally the Views :
Index.cshtml
#model WebApplication1.Models.Mymodel
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
#using (Html.BeginForm("Contact", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Mymodel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Age, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Age, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Age, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Contact, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Contact, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Contact, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Phone, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Phone, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Phone, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Sortcode, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Sortcode, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Sortcode, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Sysmcode, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Sysmcode, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Sysmcode, "", 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" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Contact.cshtml
#model WebApplication1.Models.Mymodel
<div>
<h4>Mymodel</h4>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
#Html.DisplayFor(model => model.Name)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Age)
</dt>
<dd>
#Html.DisplayFor(model => model.Age)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Contact)
</dt>
<dd>
#Html.DisplayFor(model => model.Contact)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Phone)
</dt>
<dd>
#Html.DisplayFor(model => model.Phone)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Address)
</dt>
<dd>
#Html.DisplayFor(model => model.Address)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Sortcode)
</dt>
<dd>
#Html.DisplayFor(model => model.Sortcode)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Sysmcode)
</dt>
<dd>
#Html.DisplayFor(model => model.Sysmcode)
</dd>
</dl>
</div>
<p>
#Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
#Html.ActionLink("Back to List", "Index")
</p>
Validations working fine.
Hope this helps.

MVC validation focusing the date time control on validation fail

I am having my view as follows
#using (Html.BeginForm("Apply", "Leave", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="form-group">
Leave Type
#Html.DropDownListFor(m => m.LeaveTypeId, Model.LeaveType, "Choose...", new { #class = "form-control", #tabindex = "1" })
#Html.ValidationMessageFor(m => m.LeaveTypeId, "", new { #class = "label-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="form-group">
From Date
#Html.TextBoxFor(m => m.FromDate, new { #class = "form-control", #tabindex = "2" })
#Html.ValidationMessageFor(m => m.FromDate, "", new { #class = "label-danger" })
</div>
</div>
}
When I click on apply button it is auto focusing the next control as my tab index was set. So is there any way to focus but not display the datetime control

Show only server side errors in validation summary

I have the following view:
#model MyProject.Models.RegisterViewModel
<div class="content">
<div class="wrapper">
<h2>E-Bill Saver Registration</h2>
<hr />
<div class="columns top-gap">
<div class="first cell width-6 dark-blue-headings">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#*#Html.ValidationSummary("", new { #class = "text-danger" })*#
<div class="form-horizontal">
<div class="form-group">
#Html.Label("Account Number", htmlAttributes: new { #class = "control-label col-md-2 bold" })
<br />#Html.ValidationMessageFor(model => model.AccountNo, "", new { #class = "text-danger" })
<div class="col-md-10">
#Html.EditorFor(model => model.AccountNo, new { htmlAttributes = new { #class = "form-control input" } })
</div>
</div>
<div class="form-group">
#Html.Label("MPNumber", htmlAttributes: new { #class = "control-label col-md-2 bold" })
<br />#Html.ValidationMessageFor(model => model.MPNumber, "", new { #class = "text-danger" })
<div class="col-md-10">
#Html.EditorFor(model => model.MPRN, new { htmlAttributes = new { #class = "form-control input" } })
</div>
</div>
<div class="form-group">
#Html.Label("Email Address", htmlAttributes: new { #class = "control-label col-md-2 bold" })
<br />#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control input" } })
</div>
</div>
<div class="form-group">
#Html.Label("Confirm Email Address", htmlAttributes: new { #class = "control-label col-md-2 bold" })
<br />#Html.ValidationMessageFor(model => model.ConfirmEmail, "", new { #class = "text-danger" })
<div class="col-md-10">
#Html.EditorFor(model => model.ConfirmEmail, new { htmlAttributes = new { #class = "form-control input" } })
</div>
</div>
<div class="form-group">
#Html.Label("Password", htmlAttributes: new { #class = "control-label col-md-2 bold" })
<br />#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control input" } })
</div>
</div>
<div class="form-group">
#Html.Label("Confirm Password", htmlAttributes: new { #class = "control-label col-md-2 bold" })
<br />#Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { #class = "text-danger" })
<div class="col-md-10">
#Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { #class = "form-control input" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Register" class="opc_button" />
</div>
</div>
</div>
}
</div>
</div>
</div>
If there are validation errors on any of the fields then the error message is displayed below the label as expected and wanted. On my controller however I have some custom logic errors and I am adding them to the modelstate as follows:
else
{
//This email address is already assigned to a user
ModelState.AddModelError("Email Address : ", "Error! You must enter an email address that is unique to your account.");
return View(model);
}
If I uncomment the validationsummary on my page then it will display the custom server side error but it will also display the single validation errors which I want underneath the labels. Is there any way that I can set the validation summary to ignore the values that are being listed individually and only return server side validation errors?
The first string parameter of ModelState.AddModelError method is the key later used to bind the message to the model property.
If you want to display that error message next to email label, make first parameter of AddModelError match your property name:
ModelState.AddModelError("Email", "Error! Email already used...");

Model binding doesn't work when multiple instances of the same partial view are called dynamically with ajax.actionlink in MVC 5

I'm building a restaurant reservations system. When the user creates a reservation they can also decided what furniture will be used with the reservation. For this I created a partial view, so every time the user click on "add furniture" the partial view is loaded with ajax where the user can then specify what furniture and how many. They can add as many types of furniture as they want, meaning they can call the partial view as many times as they want. My problem comes in with the model binder, the model binder then have bind all those partial view instances to a list object of type "BistroReservations_ReservationsFurniture". Please help how to make the model binder work.
MainView (Please have a look at the bottom for the ajax.actionlink call "Add Furniture"
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>BistroReservations_Reservation</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.DateOfArrival, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DateOfArrival, new { htmlAttributes = new { #class = "form-control datecontrol" } })
#Html.ValidationMessageFor(model => model.DateOfArrival, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BistroReservations_ShiftID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("BistroReservations_ShiftID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BistroReservations_ShiftID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BistroReservations_GuestID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-6">
#Html.DropDownList("BistroReservations_GuestID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BistroReservations_GuestID, "", new { #class = "text-danger " })
#Ajax.ActionLink("Create a New Guest", "NewGuest", new AjaxOptions
{
HttpMethod = "GET",
UpdateTargetId = "NewGuest",
InsertionMode = InsertionMode.ReplaceWith,
})
</div>
</div>
<div id="NewGuest" class="form-group">
</div>
<br />
<div class="form-group">
#Html.LabelFor(model => model.ArrivalTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ArrivalTime", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ArrivalTime, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LocationID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("LocationID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.LocationID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BistroReservations_TypeOfSeatingID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("BistroReservations_TypeOfSeatingID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BistroReservations_TypeOfSeatingID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TableNoID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("TableNoID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TableNoID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BistroReservations_StatusID, "BistroReservations_StatusID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("BistroReservations_StatusID",null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BistroReservations_StatusID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comment, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor( model => model.Comment, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Comment, "", new { #class = "text-danger" })
#Ajax.ActionLink("Add Furniture", "Furniture", new AjaxOptions
{
HttpMethod = "GET",
UpdateTargetId = "Furniture",
InsertionMode = InsertionMode.InsertAfter
})
</div>
</div>
<div id="Furniture" class="form-group">
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
ActionResult returning the furniture partial view
public PartialViewResult Furniture()
{
ViewBag.BistroReservations_FurnitureID = new SelectList(db.BistroReservations_Furnitures, "BistroReservations_FurnitureID", "Description");
return PartialView("_Furniture");
}
Furniture partial view
#model CdvPortal.Models.BistroReservations.BistroReservations_ReservationFurniture
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.BistroReservations_FurnitureID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("BistroReservations_FurnitureID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BistroReservations_FurnitureID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group ">
#Html.LabelFor(model => model.Quantity, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Quantity, "", new { #class = "text-danger" })
</div>
</div>
</div>
Furniture Model
public class BistroReservations_ReservationFurniture
{
public int BistroReservations_ReservationFurnitureID { get; set; }
public int BistroReservations_ReservationID { get; set; }
public virtual BistroReservations_Reservation BistroReservations_Reservation { get; set; }
[Display(Name="Furniture Type")]
public int BistroReservations_FurnitureID { get; set; }
public virtual BistroReservations_Furniture BistroReservations_Furniture { get; set; }
public int Quantity { get; set; }
}
You #Ajax.ActionLink() method is returning views with duplicate id attributes (invalid html) and duplicate name attributes which are not prefixed with the correct property name and do not include indexers for binding to a collection. For example if the collection property is named FurnitureItems then the html needed for the Quantity property of typeof BistroReservations_ReservationFurniture would need to be
<input type="text" name="FurnitureItems[0].Quantity" ...>
<input type="text" name="FurnitureItems[1].Quantity" ...>
You can use the BeginCollectionItem helper to generate the controls, which might look like (assuming the property is named FurnitureItems)
#model CdvPortal.Models.BistroReservations.BistroReservations_ReservationFurniture
#using (Html.BeginCollectionItem("FurnitureItems"))
{
....
#Html.LabelFor(m => m.Quantity, ..)
#Html.EditorFor(m => m.Quantity, ..)
#Html.ValidationMessageFor(m => m.Quantity, ..)
}
This will generate the correct prefix and add include an indexer based on a guid which also allows you to delete items from the collection. This article explains the usage in more detail
A pure client side alternative is shown in this answer. This gives better performance, but is harder to maintain since changing anything in the BistroReservations_ReservationFurniture model means updating the client side template.

Resources