Why does not data change after clicking submit button in MVC? [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
When I click Edit button to submit the data it just refreshes the page. I have spent hours to solve the problem. Though it does not show any error and it does not change the database. I can not fix the problem why it is happening.
Model class for Student
public class Student
{
[Key]
public int StudentId { get; set; }
[Required]
[Display(Name = "Student Name")]
public string StudentName { get; set; }
[Required(ErrorMessage = "please enter Email")]
[Remote("IsEmailUnique","Student",ErrorMessage = "This Email is
already Exists")]
public string Email { get; set; }
[Required(ErrorMessage = "please fill up Address")]
[DataType(DataType.MultilineText)]
public string Address { get; set; }
[Required]
public int DepartmentId { get; set; }
public virtual Department Department { get; set; }
[Display(Name = "Date of Birth")]
[Required]
[DataType(dataType:DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",
ApplyFormatInEditMode = true)]
public DateTime DoB { get; set; }
[Required]
[Remote("IsPhoneUnique", "Student", ErrorMessage = "This Phone is
already Exists")]
public string Phone { get; set; }
public string Gender { get; set; }
[Required]
[Display(Name = "Reg NO")]
[Remote("IsRegNoUnique", "Student", ErrorMessage = "This RegNo is
already Exists")]
public string RegNo { get; set; }
}
Controller for edit
[HttpGet]
public ActionResult Edit(int? id)
{
var student = db.Students.Find(id);
ViewBag.id = new SelectList(db.Departments, "DepartmentId", "
"DepartmentName");
return View(student);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Student student)
{
if (ModelState.IsValid)
{
db.Entry(student).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.id = new SelectList(db.Departments, "DepartmentId", "DepartmentName", student.DepartmentId);
return View(student);
}
View for Edit
#model CampusManagementApp.Models.Student
#{
ViewBag.Title = "Make A Booking";
HtmlHelper.ClientValidationEnabled = false;
}
<h2>Edit</h2>
#using (Html.BeginForm("Edit", "Student"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Student</h4>
<hr />
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.StudentId)
<div class="form-group">
#Html.LabelFor(model => model.StudentName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StudentName)
#Html.ValidationMessageFor(model => model.StudentName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DepartmentId, "DepartmentId", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("DepartmentId",
(IEnumerable<SelectListItem>)ViewBag.id,
"Select department")
#Html.ValidationMessageFor(model => model.DepartmentId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DoB, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DoB)
#Html.ValidationMessageFor(model => model.DoB)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Phone, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Phone)
#Html.ValidationMessageFor(model => model.Phone)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Gender, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<b>Male</b>#Html.RadioButton("Gender", "Male")
<b>Female</b>
#Html.RadioButton("Gender", "Female")
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
What can be done to solve the problem?

You have at least one validation error, because RegNo is required and is not even part of your view.
As suggested in the comments, best is to put a breakpoint on this line of your controller:
if (ModelState.IsValid)
And check if there are any other validation errors...

Related

How do I use two dropdown menu instances from the same model?

I am having an issue where I think I have set things up correctly, however the results are alway nil.
Here's the three models:
public class FamilyMember
{
[Key]
public int id { get; set; }
[Required]
[Display(Name = "First Name")]
public string firstName { get; set; }
[Required]
[Display(Name = "Surname")]
public string surname { get; set; }
[Required]
[Display(Name = "Date of Birth")]
public DateTime dob { get; set; }
public virtual FamilyRelationship FamilyRelationship { get; set; }
[Display(Name = "Full Name")]
public string fullName
{
get
{
return string.Format("{0} {1}", firstName, surname);
}
}
}
public class RelationshipType
{
[Key]
public int id { get; set; }
[Required]
[Display(Name="Relationship Type")]
public string relationshipType { get; set; }
public virtual FamilyRelationship FamilyRelationship { get; set; }
}
public class FamilyRelationship
{
[Key]
public int id { get; set; }
[ForeignKey("FamilyMembers")]
[Display(Name = "First Family Member")]
public int familyMemberPrimary { get; set; }
[ForeignKey("FamilyMembers")]
[Display(Name = "Second Family Member")]
public int familyMemberSecondary { get; set; }
[Display(Name = "Relationship Type")]
public int relationshipType { get; set; }
public virtual ICollection<FamilyMember> FamilyMembers { get; set; }
public virtual ICollection<RelationshipType> RelationshipTypes { get; set; }
}
So, I have successfully added data to FamilyMember and RelationshipType and the CRUD is working perfectly.
The problem is found in the Create Controller/View of FamilyRelationship. The dropdown works perfectly and shows the family members in the two associated menus and the relationship also shows on the relationType dropdown. However, when I click create all values are set to null.
Create Controller:
// GET: FamilyRelationships/Create
public ActionResult Create()
{
ViewBag.familyMember = new SelectList(db.FamilyMembers, "id", "fullName");
ViewBag.relationship = new SelectList(db.RelationshipTypes, "id", "relationshipType");
return View();
}
// POST: FamilyRelationships/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "id,familyMemberPrimary,familyMemberSecondary,relationshipType")] FamilyRelationship familyRelationship)
{
if (ModelState.IsValid)
{
db.FamilyRelationships.Add(familyRelationship);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(familyRelationship);
}
Create View:
#model FamilyTree.Models.FamilyRelationship
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>FamilyRelationship</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.familyMemberPrimary, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#*#Html.EditorFor(model => model.familyMemberPrimary, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.familyMemberPrimary, "", new { #class = "text-danger" })*#
#Html.DropDownList("familyMember", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.familyMemberPrimary, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.familyMemberSecondary, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("familyMember", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.familyMemberPrimary, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.relationshipType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("relationship", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.relationshipType, "", 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>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Please let me know where am I going wrong and if possible provide an example to make this work.
#Html.DropDownList("familyMember"
you need to use the actual property names most likely
#Html.DropDownList("familyMemberPrimary"
you'd also have to rename the viewbag property to match for the items to show up.. or use dropdownlistfor
#Html.DropDownListFor(a => a.familyMemberPrimary, (SelectList)ViewBag.familyMember , new { #class = "form-control" })
you also need to add a dropdownlist for familyMemberSecondary
#Html.DropDownListFor(a => a.familyMemberSecondary, (SelectList)ViewBag.familyMember , new { #class = "form-control" })
This should get you pretty close..
#model FamilyTree.Models.FamilyRelationship
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>FamilyRelationship</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.familyMemberPrimary, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(a => a.familyMemberPrimary, (SelectList)ViewBag.familyMember, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.familyMemberPrimary, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.familyMemberSecondary, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(a => a.familyMemberSecondary, (SelectList)ViewBag.familyMember, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.familyMemberSecondary, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.relationshipType, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(a => a.relationshipType, (SelectList)ViewBag.relationship, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.relationshipType, "", 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>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
make sure you re set your ViewBag properties after a failed POST
DotNetFiddle Example
This is the expected behaviour. Remember Http is stateless. So you need to reload your dropdown data before returning to the view
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "id,familyMemberPrimary,familyMemberSecondary,
relationshipType")] FamilyRelationship familyRelationship)
{
if (ModelState.IsValid)
{
db.FamilyRelationships.Add(familyRelationship);
db.SaveChanges();
return RedirectToAction("Index");
}
//Let's reload the data for dropdown.
ViewBag.familyMember = new SelectList(db.FamilyMembers, "id", "fullName");
ViewBag.relationship = new SelectList(db.RelationshipTypes, "id", "relationshipType");
return View(familyRelationship);
}
EDIT: As per comment
The values within the FamilyRelationship so familyMemberPrimary,
familyMemberSecondary and relationshipType have values of 0, where I
was expecting the id's of each of these would be passed over.
Because you are using EditorFor helper method for familyMemberPrimary property in your view. So if you are not filling a value in that input field, it is going to have default value(0 for int type)
If you want that property to be filled with your dropdown selection(of family members), you should give the dropdown name value as familyMemberPrimary so that when you post the form, model binding will set the selected option value to familyMemberPrimary property.
#Html.DropDownList("familyMemberPrimary",
ViewBag.familyMember as IEnumerable<SelectListItem>,
htmlAttributes: new { #class = "form-control" })

How to select data via partial view

I have a partial view that returns a list of users address's, I need the user to be able to select one, then when they press "submit" along with the other details it takes the details from the selected address returns it to the controller, from there I know how to assign it where I want. How would I do this? Examples and help appreciated
Here is my controller for creating the order, view beneath;
[HttpPost]
public ActionResult AddressAndPayment(FormCollection values, string id)
{
var order = new Order();
TryUpdateModel(order);
//sets date and username
order.Username = User.Identity.Name;
order.OrderDate = DateTime.Now;
//Order gets saved
storeDB.Orders.Add(order);
storeDB.SaveChanges();
//Order gets processed
var cart = ShoppingCart.GetCart(this.HttpContext);
cart.CreateOrder(order);
//Save again, total not saving properly until now
storeDB.SaveChanges();
return RedirectToAction("Complete",
new { id = order.OrderId });
}
VIEW
#model T_shirt_Company_v3.Models.Order
#{
ViewBag.Title = "Address And Payment";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.HiddenFor(x => x.OrderId)
#Html.HiddenFor(x => x.OrderDate)
#Html.HiddenFor(x => x.PaymentTransactionId)
#Html.HiddenFor(x => x.Total)
#Html.HiddenFor(x => x.Username)
<div class="form-horizontal">
<h2>Address And Payment</h2>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#{Html.RenderAction("Listofaddresses", "Checkout");}
<h2>Select Postage type</h2>
#Html.EnumDropDownListFor(model => model.PostageList, "-- Please select postage type --")
<h2>Payment</h2>
<div class="form-group">
#Html.LabelFor(model => model.cardDetails.FullName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.cardDetails.FullName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.FullName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.cardDetails.CardNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.cardDetails.CardNo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.CardNo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.cardDetails.CardExpireMonth, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="row">
<div class="col-md-1">
#Html.EditorFor(model => model.cardDetails.CardExpireMonth, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.CardExpireMonth, "", new { #class = "text-danger" })
</div>
<div class="col-md-1">
#Html.EditorFor(model => model.cardDetails.CardExpireYear, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.CardExpireYear, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.cardDetails.Cvc, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.cardDetails.Cvc, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.Cvc, "", 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>
}
Partial View
#model IEnumerable<T_shirt_Company_v3.Models.deliveryAddress>
#foreach (var item in Model)
{
<div style="width: 180px">
<div class="thumbnail">
<p>#Html.DisplayFor(modelItem => item.FirstName) #Html.DisplayFor(modelItem => item.LastName) </p>
<p>#Html.DisplayFor(modelItem => item.Address)</p>
<p>#Html.DisplayFor(modelItem => item.City)</p>
<p>#Html.DisplayFor(modelItem => item.PostalCode)</p>
<p>#Html.DisplayFor(modelItem => item.Country)</p>
</div>
</div>
}
Address Class
public class deliveryAddress
{
[Key]
[ScaffoldColumn(false)]
public int AdressId { get; set; }
[ScaffoldColumn(false)]
public string UsersAddress { get; set; }
[Required]
[StringLength(16, ErrorMessage = "Your name is too long")]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Your last name is required.")]
[StringLength(16, ErrorMessage = "Last name is too long.")]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required(ErrorMessage = "Address is required.")]
public string Address { get; set; }
[Required(ErrorMessage = "City is required.")]
public string City { get; set; }
[Required(ErrorMessage = "Postcode is required.")]
[Display(Name = "Post Code")]
public string PostalCode { get; set; }
[Required(ErrorMessage = "Country is required.")]
public string Country { get; set; }
[Required(ErrorMessage = "Phone home number is required.")]
[Display(Name = "Home Telephone")]
public string Phone { get; set; }
[Required(ErrorMessage = "Phone mobile number is required.")]
[Display(Name = "Mobile")]
public string Mobile { get; set; }
}
}

Bind unknown number of Input elements to model in MVC5

I am fairly new to MVC5 and C# and I am trying to achieve something that I don't fully understand.
I have a Team Model such as this:
public class Team
{
[Key]
public Guid ID { get; set; }
public string TeamName { get; set; }
public string Coach { get; set; }
public string Conference { get; set; }
}
I also have a Player Model such as this:
public class Player
{
[Key]
public Guid Id { get; set; }
[ForeignKey("Teams")]
public Guid TeamId { get; set; }
public string Name { get; set; }
public virtual Team Teams { get; set; }
}
View Model is
public class TeamViewModel
{
public string TeamName { get; set; }
public string Coach { get; set; }
public string Conference { get; set; }
public List<Player> Players { get; set; }
}
With this structure, you are suppose to be able to add and infinite number of players to each team. As such I have a Teams table with few properties and a Player table that contains the player name as well as the player TeamId so that we know to what team they belong.
My problem comes when I am creating a team. I have Create Controller such as this:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(TeamViewModel model)
{
if (ModelState.IsValid)
{
var team = new Team { TeamName = model.TeamName, Coach = model.Coach, Conference = model.Conference, Player = model.Player };
db.Teams.Add(team);
var result = await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View();
}
And my View is as follows:
#model SoccerTeams.Models.ViewModels.TeamViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Team</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.TeamName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TeamName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TeamName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Coach, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Coach, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Coach, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Conference, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Conference, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Conference, "", new { #class = "text-danger" })
</div>
</div>
#if (#Model != null)
{
foreach (var p in Model.Player)
{
<div class="form-group">
#Html.Raw("<label class=\"control-label col-md-2\">" + p.ToString() + "</label>")
<div class="col-md-10">
#Html.Raw("<input class=\"form-control text-box single-line\" name=\"Player\" type-\"text\"")
</div>
</div>
}
}
else
{
<div class="form-group">
#Html.Raw("<label class=\"control-label col-md-2\">Player</label>")
<div class="col-md-10">
#Html.Raw("<input class=\"form-control text-box single-line\" name=\"Player\" type-\"text\"")
</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>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
From my understanding, the View is suppose to be able to convert the input element to a list and pass it on to my ViewModel. However, my ViewModel is always coming up as null.
What am I missing and how would I make this work?
P.S. I understand that I can user Html.EditorFor, but I was not able to get it working, so I just printed it out as Html as I need to solve my other problem first.
Edit
I have altered my View to have the following code
<div class="form-group">
#Html.Raw("<label class=\"control-label col-md-2\">Player</label>")
<div class="col-md-10">
#Html.Raw("<input class=\"form-control text-box single-line\" name=\"model.Players[0].Name\" type-\"text\"")
</div>
</div>
As a result, the model now properly populates the Players Array, however all other values have now become null. If I remove the input element, the values are populated but players array is null again as there are no form fields for it. Do you know what could be the culprit?
In the TeamViewModel I have also renamed Player to Players.
In order for MVC to bind your form data to the Action method's parameters
their names should match.
Supposing your ViewModel has property for List<Player> Players your code should be:
In your case:
foreach (var p in Model.Player)
{
<div class="form-group">
#Html.Raw("<label class=\"control-label col-md-2\">" + p.ToString() + "</label>")
<div class="col-md-10">
#Html.Raw("<input class=\"form-control text-box single-line\" name=\"Player\" type-\"text\"")
</div>
</div>
}
Should be:
for (int i = 0; i < Model.Player.Length; i++)
{
<div class="form-group">
#Html.Raw("<label class=\"control-label col-md-2\">" + p.ToString() + "</label>")
<div class="col-md-10">
#Html.Raw("<input class=\"form-control text-box single-line\" name=\"model.Player[" + i + "].Name\" type-\"text\"")
</div>
</div>
}
Because this is the name of the parameter that you have provided:
Create(TeamViewModel model)
Also be careful because the indexes should not be broken, which means that they should be 0, 1, 2.. etc. without skipping a number.
The way that we read in the properties is by looking for
parameterName[index].PropertyName. The index must be zero-based and
unbroken.
NOTE You can read more about binding collections in Scott Hanselman's post - here
And last I suggest if you have a property that is list of something - in your case list of Player to use the plural form for the property name - Players.
EDIT
Try removing the "model." in front in the name. Make it like this "Players[0].Name". Since you only have one parameter in your Create Action method it should be fine.
I suggest you to use the helper #Html.EditorFor, so to do this you will create a partial view that will be used as template to inputs of the nested property. see the example:
Shared/EditorTemplates/Player.cshtml
#model Player
<div class="form-group">
#Html.HiddenFor(e => e.Id)
#Html.HiddenFor(e => e.TeamId)
<label class="control-label col-md-2" for="player">Player</label>
<div class="col-md-10">
#Html.TextBoxFor(e => e.Name, new { #class = "form-control text-box single-line", id = "player", name = "Player"})
</div>
</div>
Players form on Team view:
#Html.EditorFor(e => e.Player)
Instead of:
foreach (var p in Model.Player)
{
<div class="form-group">
#Html.Raw("<label class=\"control-label col-md-2\">" + p.ToString() + "</label>")
<div class="col-md-10">
#Html.Raw("<input class=\"form-control text-box single-line\" name=\"Player\" type-\"text\"")
</div>
</div>
}
See this article for more information about editor templates: Editor and display templates

ValidationMessageFor automatically getting fred

I have an actionmethod resetpassword which is of type get which returns a view. The method gets called from an actionlink button. To this view I am passing a user obj. Now when I click on the actionlink , it goes to the view but as I have applied validationfor the validations are getting fired automatically when the view is loaded. Is this because I am passing an obj of user to the view.? If that's the case, then how can i turn off the validations for HttpGet for that action method as I only want to load the inputs and when the user starts filling in the inputs then only validation should fire.
Action Method.
[ValidateInput(false)]
[HttpGet]
[ActionName("ResetPassword")]
public ActionResult ResetPassword(UserBE user)
{
user.Email = TempData["userEmail"].ToString();
return View(user);
}
View
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
#model XYZ.BE.UserBE
#{
ViewBag.Title = "ResetPassword";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>ResetPassword</h2>
#using (Html.BeginForm("ResetPassword", "User"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model=>model.Email)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
#Html.HiddenFor(model=>model.Email)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.NewPassword, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.PasswordFor(model => model.NewPassword)
#Html.ValidationMessageFor(model => model.NewPassword)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ConfirmedPassword, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.PasswordFor(model => model.ConfirmedPassword)
#Html.ValidationMessageFor(model => model.ConfirmedPassword)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Reset Password" class="btn btn-default" />
</div>
</div>
}
ActionLink BUtton
<h3>#Html.ActionLink("Reset Password", "ResetPassword")
Post Method
[HttpPost]
[ActionName("ResetPassword")]
public ActionResult ResetPasswordPost(UserBE user)
{
user = UserBL.AuthenticateUser(user);
if (!user.AuthenticUser || (user.Password==user.NewPassword))
{
return View(user);
}
else
{
return UserBL.ResetPassword(user)?View("LoginSuccessful",user):View(user);
}
}
Model
[Required(ErrorMessage = "Password is required")]
public string Password { get; set; }
private bool authenticUser = false;
public bool AuthenticUser
{
get { return authenticUser; }
set { authenticUser = value; }
}
[Required(ErrorMessage = "Password is required")]
public string NewPassword { get; set; }
[Required(ErrorMessage = "Confirm passord and NewPassWord does not match")]
[Compare("NewPassword")]
public string ConfirmedPassword { get; set; }
I just added the following to _layout and it worked.
#Scripts.Render("~/bundles/jqueryval")

Postback when validating ASP.NET MVC Form

I created a web form form using asp.net mvc scaffolding and it does not work client side validation without postback. [Required()] is postbacking and [EmailAddress] validator is validating in client side. Im using visual studio 2013 and asp.net mvc 5 with ef6.
this id my model class :
namespace WebApplication4.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Tutor
{
public Tutor()
{
this.Examinations = new HashSet<Examination>();
}
public decimal TutorID { get; set; }
[Display(Name = "First Name ")]
[Required(ErrorMessage = "Please Enter First Name.")]
[DataType(DataType.Text)]
public string FirstName { get; set; }
[Display(Name = "Last Name ")]
[Required(ErrorMessage = "Please Enter Last Name.")]
[DataType(DataType.Text)]
public string LastName { get; set; }
[Display(Name = "Address Line 1 ")]
[Required(ErrorMessage = "Please Enter Address Line 1.")]
[DataType(DataType.Text)]
public string Address1 { get; set; }
[Display(Name = "Address Line 2 ")]
[Required(ErrorMessage = "Please Enter Address Line 2.")]
[DataType(DataType.Text)]
public string Address2 { get; set; }
[Display(Name = "Address Line 3 ")]
public string Address3 { get; set; }
[Display(Name = "Telephone 1 ")]
[Required(ErrorMessage = "Please Enter Telephone No.")]
[DataType(DataType.Text)]
public string Tel1 { get; set; }
[Display(Name = "Telephone 2 ")]
[DataType(DataType.Text)]
public string Tel2 { get; set; }
[Display(Name = "Email Address")]
[Required(ErrorMessage = "Please Enter E Mail Address.")]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
[DataType(DataType.EmailAddress)]
public string EMail { get; set; }
[Display(Name = "Password ")]
[DataType(DataType.Password)]
public string Password { get; set; }
public Nullable<bool> IsConfirmed { get; set; }
public virtual ICollection<Examination> Examinations { get; set; }
}
}
This is my controller Create() methods in controller:
// GET: /Default1/Create
public ActionResult Create()
{
return View();
}
// POST: /Default1/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="TutorID,FirstName,LastName,Address1,Address2,Address3,Tel1,Tel2,EMail,Password,IsConfirmed")] Tutor tutor)
{
if (ModelState.IsValid)
{
db.Tutors.Add(tutor);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(tutor);
}
This Is view for create...
#model WebApplication4.Models.Tutor
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Tutor</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.FirstName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address1, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address1)
#Html.ValidationMessageFor(model => model.Address1)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address2, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address2)
#Html.ValidationMessageFor(model => model.Address2)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address3, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address3)
#Html.ValidationMessageFor(model => model.Address3)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tel1, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Tel1)
#Html.ValidationMessageFor(model => model.Tel1)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tel2, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Tel2)
#Html.ValidationMessageFor(model => model.Tel2)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EMail, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EMail)
#Html.ValidationMessageFor(model => model.EMail)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</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>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
I want to validate all the things in client side.
Make sure you load jquery.validate.js liberary properly
BundleConfig.cs
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
At end of your page
#Scripts.Render("~/bundles/jqueryval")
Solution is to use jquery.validate.unobtrusive.js.
Once you load the form, using jquery on document ready you should parse the form
//file: your view file
#model Tutor
<script>
$(document).ready(function() {
$.validator.unobtrusive.parse($("#frm1"));
}
function onSubmit(e) {
$("#frm1").validate(); // this will validate the form and show the validation messages
if($("#frm1").valid()) {
$("#frm1").submit(); // submits the form
}
return false;//prevent default submit of form by returning false.
//also e.preventDefault() can be used.
}
</script>
//for understanding purpose using the plain form tag.
//one can use #using (Html.BeginForm())
<form id="frm1" onsubmit="onSubmit();">
<!-- your content goes here -->
<div class="form-group">
#Html.LabelFor(model => model.FirstName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
</div>
</form>

Categories

Resources