Using AspNetUsers.Id in a form - c#

What I'm wanting is for a person to register (using existing register page) then get directed to a form where their AspNetUsers.Id = UserId (on my CreateProfile page). CreateProfile is the page you are directed to when you have successfully registered. As you can see in the image in the address bar you can see the user id but it won't appear in the input box.
AccountController
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
// Registered user is given the applicant role by default
UserManager.AddToRole(user.Id, "Applicant");
// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking here");
ViewBag.UserId = user.Id;
//return RedirectToAction("Index", "Home");
return RedirectToAction("CreateProfile", new { controller = "Admin", UserId = user.Id });
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
CreateProfile View
#model NAA.Data.Profile
#{
ViewBag.Title = "CreateProfile";
}
<h2>Create Profile</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Profile</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ApplicantName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ApplicantName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ApplicantName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ApplicantAddress, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ApplicantAddress, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ApplicantAddress, "", 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.Email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.UserId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.UserId, new { htmlAttributes = new { #class = "form-control", } })
#Html.ValidationMessageFor(model => model.UserId, "", 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", "GetProfile", new { controller = "Profile", action = "GetProfile" })
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Image of CreateProfile
Controller Action

you have two main problems:
In Register action you pass userId value using ViewBag and later use RedirectToAction. You cannot use ViewBag for this scenario, because value will loss. Check here
You don't assign UserId value on input box [CreateProfile view].
To solve it:
Capture UserId value in CreateProfile Get Action and later assign in ViewBag to pass value to View. Two forms:
a. Use MVC bind, set a variable:
// Get: Admin/CreateProfile
public ActionResult CreateProfile(string UserId) // <== here
{
ViewBag.UserId = UserId;
return View();
}
b. Use request object to get value.
// Get: Admin/CreateProfile
public ActionResult CreateProfile()
{
ViewBag.UserId = Request.Params["UserId"]; // <== here
return View();
}
Optional: you could save UserId value using Session Object in Register Action. Maybe I would like this because avoid before code. Check here.
Finally assign UserId value on input box in CreateProfile view using #Value:
new { htmlAttributes = new { #class = "form-control", #Value=
ViewBag.UserId }
I.E:
<div class="form-group">
#Html.LabelFor(model => model.UserId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.UserId, new { htmlAttributes = new { #class = "form-control", #Value= ViewBag.UserId } })
#Html.ValidationMessageFor(model => model.UserId, "", new { #class = "text-danger" })
</div>
</div>

Related

DropDownListFor post value NULL to database

I have a Course Table and a Hole Table in SQL. There is a foreign Key in the hole Table that is set to the CourseId.
This is so that when I create a hole I can assign it to the relevant course.
In my View I have a dropdownlistfor that has a list of courses to select from when creating the hole. However when I try and post back the values the courseID does not post back.
HoleViewModel
// GET: HoleViewModels/Create
public ActionResult Create()
{
var dbcourse = db.Course.ToList();
//Make selectlist, which is IEnumerable<SelectListItem>
var courseNameDropdownList = new SelectList(db.Course.Select(item => new SelectListItem()
{
Text = item.CourseName.ToString(),
Value = item.CourseId.ToString()
}).ToList(), "Value", "Text");
// Assign the Selectlist to the View Model
var viewCourse = new HoleViewModel()
{
Course = dbcourse.FirstOrDefault(),
// The Dropdownlist values
CourseNamesDropdownList = courseNameDropdownList,
};
return View(viewCourse);
}
// POST: HoleViewModels/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "HoleId,HoleNumber,Par,Length,StrokeIndex,CourseId")] HoleViewModel holeViewModel)
{
if (ModelState.IsValid)
{
db.HoleViewModels.Add(holeViewModel);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(holeViewModel);
}
The Create.cshtml
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>HoleViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.HoleNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.HoleNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.HoleNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Par, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Par, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Par, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Length, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Length, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Length, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StrokeIndex, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StrokeIndex, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.StrokeIndex, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Course.CourseId, "CourseId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Course.CourseId, Model.CourseNamesDropdownList, "Please select from List", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CourseId, "", new { #class = "text-danger" })
</div>
</div>
So when the holeview posts back holeNumber, Par, Length, StrokeIndex, CourseID. it passes all data into the hole table other than the courseId which it posts a null.
What am I missing from the POST to get the CourseId to be entered in the Database.

Invalid username or password eroor page

I'm setting up a Car Sales project and I want an error page whenever I enter wrong username or password.
I have tried with the [HandleError] attribute, now I'm trying with Membership.ValidateUser. I'm a bit confused about which one I should use all I know is HandlerError attribute is for specific errors.
[HttpPost]
public ActionResult Login(User user)
{
using (CarsDBEntities db = new CarsDBEntities())
{
var usr = db.Users.Single(u => u.Email == user.Email && u.Password == user.Password);
if (usr != null)
{
Session["UserId"] = usr.UserId.ToString();
Session["Email"] = usr.Email.ToString();
Session["FirstName"] = usr.FirstName.ToString();
Session["LastName"] = usr.LastName.ToString();
return RedirectToAction("LoggedIn");
}
if (!Membership.ValidateUser(usr.Email, usr.Password))
{
ModelState.AddModelError(string.Empty, "The user name or password is incorrect");
return View(user);
}
return View();
}
}
This is my view
#model Car_Sales.Models.User
#{
ViewBag.Title = "Login";
}
<h2>Login</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>User</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Login" class="btn btn-default" />
</div>
</div>
</div>
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
I expected it to show an error which tells the user that he/she entered incorrect credentials.
Why don't you just redirect to a new View or Action or Controller?
Example:
if (!Membership.ValidateUser(usr.Email, usr.Password))
{
return RedirectToAction("Error","SomeAction")
}

How to get back uploaded image in edit mode in my form using ASP.NET MVC 5?

I have created a form and I am inserting some data and image in my database using the form submit... But when I am opening in edit mode, all inserted data is available in the input fields except the image? How do I fix this?
View:
#model User_Management_System_V2._0.Models.Product
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm("Edit","Products",FormMethod.Post , new { enctype = "multipart/form-data"}))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Product</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#*<div class="form-group">
#Html.LabelFor(model => model.ProductID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProductID, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductID, "", new { #class = "text-danger" })
</div>
</div>*#
#Html.HiddenFor(model => model.ProductName)
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PriceExpected, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PriceExpected, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PriceExpected, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OldTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OldTime, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.OldTime, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Status, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Status, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Status, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Photo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="file"/>
#Html.ValidationMessageFor(model => model.Photo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Controller:
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Product product = db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
return View(product);
}
Create Action
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create([Bind(Include = "ProductName,Description,PriceExpected,OldTime,Status,Photo")]Product product,HttpPostedFileBase file)
{
if (file != null)
{
product.Photo = new byte[file.ContentLength];
file.InputStream.Read(product.Photo, 0, file.ContentLength);
}
else
{
ModelState.AddModelError("", "Please Select image");
}
db.Products.Add(product);
db.SaveChanges();
return RedirectToAction("Index");
}
My main problem is that all the fields are opening in edit mode which means they are opening in edit mode with the preinserted data values in their fields but the image is not having the preinserted value.
try the following solution in jquery and pure Javascript you will only need to retrieve byte array of the image you uploaded and it's extension then just give your image control the generated src I hope it helps
var PhotoArr = []; //array of bytes from the server
var PhotoExt = "jpg";//example
if (PhotoArr) {
var byteArray = new Uint8Array(oldResume.PhotoArr);
var blob = new Blob([byteArray], { type: 'application/' + PhotoExt });
var image = $('#yourImageId');
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL(blob);
image.attr('src', imageUrl);
}

MVC 5 Creation of foreign key entities during primary entity creation

I am utterly new to MVC and asp.net with Entity Framework so I am sure that most of my trouble stems from not knowing the proper terminology for what I am trying to do.
I have an "Address" database table/ entity that is a street address. Rather than having the street address fields in every entity that has an associated address, I simply have a foreign key column that points to the correct address in the address table.
For my Location creation view model, I have the following
public class LocationCreationViewModel
{
public address Address { get; set; }
[Key]
public location Location { get; set; }
}
It is probably worth pointing out that that View model is "hand made" while the address and location member objects are managed by the entity framework
My Create View has all of the location data, and then includes a partial address view which is rendered with
Html.Partial("_AddressCreate", Model.Location)
What currently happens is the LocationCreationViewModel returned in the Create(model) function is LocationCreationViewModel is null, or each of the fields is null. In any event, none of the data from the view is populated in the view model.
What I want to happen is that I get back the 2 addresses, add them to the address table in the database, then add my order to the order database with FK address fields pointing to the 2 newly created addresses.
I am using MVC5 and EF6 in visual studio 2017
Create.cshtml
#model MyWeb.Models.LocationCreationViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>location</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Location.name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Location.name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Location.name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Location.address, "address", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("address", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Location.address, "", new { #class = "text-danger" })
</div>
</div>
#Html.Partial("_AddressPartial", Model.Address)
<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>
_AddressPartial.cshtml
#model MyWeb.Data.address
<div class="form-horizontal">
<h4>address</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.country, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.country, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.country, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.locality, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.locality, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.locality, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.postalCode, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.postalCode, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.postalCode, "", new { #class = "text-danger" })
</div>
</div>
</div>
LocationController::Create
[MyWebAuthorize(MyWebRole = MyWebRole.Admin)]
public ActionResult Create()
{
ViewBag.address = new SelectList(db.addresses, "id", "country");
ViewBag.id = new SelectList(db.inventories, "locationID", "locationID");
LocationCreationViewModel model = new LocationCreationViewModel();
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create( LocationCreationViewModel location)
{
if (ModelState.IsValid)
{
db.addresses.Add(location.Address); //null reference exception here
db.locations.Add(location.Location);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.address = new SelectList(db.addresses, "id", "country", location.Location.address);
ViewBag.id = new SelectList(db.inventories, "locationID", "locationID", location.Location.id);
return View(location);
}
The autobinder failed to bind form data because of the field name Location in the View Model. I assume that this is due to Location being part of the page route. IE for the LocationController, the route would be /Location/Create
In any event, renaming LocationCreationViewModel::Location to LocationCreationViewModel::Locus fixed everything.

Asp.net mvc DropdownList giving null reference error

I am trying to populate a dropdownlist and then post it to db but for some reason it is giving error, please advice.
Controller
public class StudentController : BaseController
{
private List<SelectListItem> _gendersList;
[HttpGet]
public ActionResult Create()
{
var model = new CreateStudent();
_gendersList = new List<SelectListItem>()
{
new SelectListItem { Text = Constants.Gender.Boy, Value = Constants.Gender.Boy},
new SelectListItem { Text = Constants.Gender.Girl, Value = Constants.Gender.Girl},
};
model.Genders = _gendersList;
return View(model);
}
[HttpPost]
public ActionResult Create(CreateStudent student)
{
var result = true;
_gendersList = new List<SelectListItem>()
{
new SelectListItem { Text = Constants.Gender.Boy, Value = Constants.Gender.Boy},
new SelectListItem { Text = Constants.Gender.Girl, Value = Constants.Gender.Girl},
};
if (ModelState.IsValid)
{
result = _student.Insert(mappedStudent);
if (result)
{
return RedirectToAction("Index");
}
else
{
TempData["Message"] = "Failed to create new student";
return View();
}
}
return View("Create");
}
}
View
#model CreateStudent
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-3.1.1.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<h2>Create</h2>
#{
if (TempData["Message"] != null)
{
<h3>
#TempData["Message"].ToString()
</h3>
}
}
#{
}
#using (Html.BeginForm("Create","Student",FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Student</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MiddleName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(model => model.MiddleName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MiddleName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Gender, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#*#Html.DropDownListFor(o=>o.Gender,Model.StudentGender, "", new { #class = "form-control" })*#
#Html.DropDownListFor(o=>o.Gender,(List<SelectListItem>)Model.Genders,"1", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Gender, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IdNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.IdNo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.IdNo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SchoolIdNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SchoolIdNo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SchoolIdNo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ServiceType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ServiceType, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ServiceType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comments, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Comments, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsEnabled, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsEnabled)
#Html.ValidationMessageFor(model => model.IsEnabled, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FirstNameAr, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstNameAr, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstNameAr, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MiddleNameAr, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MiddleNameAr, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MiddleNameAr, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastNameAr, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastNameAr, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastNameAr, "", 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-primary" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Your view is strongly typed to a CreateStudent class and the view code is using Model.Genders collection property when you use the DropDownListFor helper method. But in your http post action, you are calling the return View() method without passing a valid CreateStudent object and in another case without populating the Genders property. So when razor executes the view code, the model value is null ( because you did not pass anything to the view)
You need to set the Genders property again before returning the posted view model back to the view.
[HttpPost]
public ActionResult Create(CreateStudent student)
{
var genderList = new List<SelectListItem>()
{
new SelectListItem { Text = Constants.Gender.Boy, Value = Constants.Gender.Boy},
new SelectListItem { Text = Constants.Gender.Girl, Value = Constants.Gender.Girl},
};
if (ModelState.IsValid)
{
var result = _student.Insert(mappedStudent);
if (result)
{
return RedirectToAction("Index");
}
else
{
student.Genders = genderList;
TempData["Message"] = "Failed to create new student";
return View(student); // Passing the object here to view
}
}
//Model validation fails. Return the same view
student.Genders = genderList;
return View(student);
}
}
Also there no need for an extra casting. Model.Genders is of type List<SelectListItem>
#Html.DropDownListFor(o=>o.Gender,Model.Genders, new { #class = "form-control" })

Categories