I have a page to create objects, and in this I have a DropDownList. If I select an item from the list my page will save correctly, however if I don't select an item it looks like it fails on a postback as the objects will be null.
What I want is to try and validate whether the user has selected an item (default is "Please Select...").
I have code that will check and see in the controller if the item is null, but it's how do I then display a message? Keeping all other details if they exist.
public ActionResult Create(int objectId = 0)
{
var resultModel = new MyObjectModel();
resultModel.AllObjects = new SelectList(_system.GetAllObjects(objectId));
// GetAllObjects juts returns a list of items for the drop down.
return View(resultModel);
}
[HttpPost]
public ActionResult Create(int? objectId, FormCollection collection)
{
try
{
int objectIdNotNull = 0;
if (objectId > 1)
{
objectIdNotNull = (int) objectId;
}
string objectName = collection["Name"];
int objectTypeSelectedResult = 1;
int.TryParse(collection["dllList"], out objectTypeSelectedResult);
if (!Convert.ToBoolean(objectTypeSelectedResult))
{
// So here I have discovered nothing has been selected, and I want to alert the user
return RedirectToAction("Create",
new {ObjectId = objectIdNotNull, error = "Please select an Object Type"});
}
....
return RedirectToAction(...)
}
catch
{
return View();
}
}
The above code just goes to the Create page but doesn't display an error. In my View for Create I have the following line which I assumed would display any errors:
#ViewData["error"]
Additional code
Model:
using System.Collections.Generic;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;
namespace MyNameSpace
{
public class MyObjectModel
{
[Required(ErrorMessage = "Please select an Object Type")]
public SelectList AllObjects { get; set; } // I populate the drop down with this list
}
}
View:
#model MyNameSpace.MyObjectModel
#{
ViewBag.Title = "Create";
}
<h2>Create </h2>
<p class="text-error">#ViewData["Message"]</p>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"> </script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<div class="editor-label">
#Html.LabelFor(model => model.MyObject.Name)
</div>
<div class="editor-field">
#Html.TextBoxFor(model=>model.MyObjectType.Name, new {style="width: 750px"})
#Html.ValidationMessageFor(model => model.MyObjectType.Name)
</div>
<div>
<label for="ddlList">Choose Type</label>
#if (#Model != null)
{
#Html.DropDownList("ddlList", Model.AllObjects, "Please Select...")
#Html.ValidationMessageFor(model => model.AllObjects, "An object must be selected", new { #class = "redText"})
}
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
You are validating the SelectList which is wrong
[Required(ErrorMessage = "An object must be selected")]
public SelectList AllObjects { get; set; }
Your Model should be
[Required(ErrorMessage = "Please select an Object Type")]
public int ObjectId { get; set; }
public string ObjectName { get; set; }
Your Controller(no need for form collection thats the whole point of MVC)
public ActionResult Create(int Id = 0)
{
MyObjectModel resultModel = new MyObjectModel();
var ObjectResultList = _system.GetAllObjects(Id);
var ObjectSelectList = new SelectList(ObjectResultList, "id", "Name");
ViewBag.ObjectList = ObjectSelectList;
return View(resultModel);
}
Your Post controller:
[HttpPost]
public ActionResult Create(MyObjectModel o)
{
try
{
if (ModelState.IsValid)
{
//It's valid , your code here!
return RedirectToAction("ObjectCreated", new { id = o.objectId });
}
else
{
var errors = ModelState
.Where(x => x.Value.Errors.Count > 0)
.Select(x => new { x.Key, x.Value.Errors })
.ToArray();
}
}
}
catch (Exception ex)
{
Response.Write(ex.InnerException.Message);
}
//If we get here it means the model is not valid, We're in trouble
//then redisplay the view repopulate the dropdown
var ObjectResultList = _system.GetAllObjects(objectId);
var ObjectSelectList = new SelectList(ObjectResultList, "id", "value");
ViewBag.ObjectList = ObjectSelectList;
return View(o);
}
Your View should be strongly Typed
<div class="editor-label">
#Html.LabelFor(model => model.ObjectId)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.ObjectId,
(IEnumerable<SelectListItem>)ViewBag.ObjectList, "-- Select One Object --")
#Html.ValidationMessageFor(model => model.ObjectId)
</div>
Related
so I've been trying to use a checkbox to send a list of values to a string property in my model.
but for some reason, the values are sent, even after i initialized with the bool false and left the checkbox unchecked.
these are my models
public class Profesor
{
public List<AsignaturaModelo> Asignaturas { get; set; }
public Profesor()
{
Asignaturas = new List<AsignaturaModelo>();
}
}
public class AsignaturaModelo
{
public string NombreA { get; set; }
public bool Selected { get; set; }
}
My controller
public ActionResult Create()
{
var model = new Profesor
{
Asignaturas = new[]
{
new AsignaturaModelo{NombreA = "Programacion 1", Selected = false},
new AsignaturaModelo {NombreA = "Programacion 2", Selected = false}
}.ToList()
};
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Profesor modelo)
{
try
{
if (ModelState.IsValid)
{
profesors.Add(modelo);
return RedirectToAction(nameof(Index));
}
}
catch
{
return View(modelo);
}
return View(modelo);
}
My view
#Html.EditorFor(x => x.Asignaturas)
and my EditorTemplate
#model AsignaturaModelo
<div>
#Html.CheckBoxFor(x => x.Selected)
#Html.HiddenFor(x => x.NombreA)
#Html.LabelFor(x => x.Selected, Model.NombreA)
</div>
Not sure what am i doing wrong, also sorry for the variable names. Thanks in advance!
Do you mean in the propertyProfesor modelo of post method,you only want selected item to pass their NombreA?If so,here is a demo worked.
View:
#model Profesor
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<form method="post" onsubmit="return check()">
#Html.EditorFor(x => x.Asignaturas, "EditorTemplate")
<div>
<input type="submit" beforesubmit="" value="submit" />
</div>
</form>
#section scripts{
<script type="text/javascript">
function check() {
var count = 0;
$('input[type="checkbox"]').each(function () {
var id = "#" + $(this).prop("id").replace("Selected", "NombreA");
var name = $(this).prop("name").replace("Selected", "NombreA");
var tempname = name.replace(/[0-9]/, "number").replace(/0-9/ig, "");
$('input[name="' + name.replace("NombreA", "Selected") + '"][type="hidden"]').attr("name", name.replace("NombreA", "Selected") + "_unselected");
if ($(this).prop("checked")) {
var newName = tempname.replace("number", ""+count);
$(id).attr("name", newName);
$(this).attr("name", newName.replace("NombreA", "Selected"));
count++;
} else {
$(id).attr("name", name + "_unselected");
}
})
return true;
}
</script>
}
EditorTemplate:
#model List<AsignaturaModelo>
#for (int i=0;i<Model.Count();i++)
{
<div>
#Html.CheckBoxFor(x => x[i].Selected)
#Html.HiddenFor(x => x[i].NombreA)
#Html.LabelFor(x => x[i].Selected, Model[i].NombreA)
</div>
}
Result:
I have a form that posts to an action:
public ActionResult Index()
{
CheckDataVM vm = new CheckDataVM();
vm.SerialNumbers = GetAllSerials();
vm.CustomerNames = GetAllCustomers();
vm.DateFrom = DateTime.Now.AddDays(-1);
vm.DateTo = DateTime.Now;
return View(vm);
}
[HttpPost]
public ActionResult Index(CheckDataVM v)
{
CheckDataVM vm = new CheckDataVM();
vm.SerialNumbers = GetAllSerials();
var s = vm.SerialNumbers.First().Text.ToString();
vm.Channels = GetAllChannels(s);
vm.DateFrom = DateTime.Now.AddDays(-1);
vm.DateTo = DateTime.Now;
return View(vm);
}
In my Razor view, I have post:
#using (Html.BeginForm("Index", "CheckData", FormMethod.Post, new { id = "SerialsForm" }))
{
<div class="card-body" style="font-size: small;">
<div class="form-group">
#Html.DropDownListFor(x => x.SelectedSerial, Model.SerialNumbers, new { #class = "form-control form-control-sm" })
<input type="submit" value="Submit" />
</div>
</div>
}
The view model is:
public class CheckDataVM
{
public string CustomersName { get; set; }
public string SelectedSerial { get;set; }
[Display(Name="Select a serial number")]
public IEnumerable<SelectListItem> SerialNumbers { get; set; }
}
The dropdowns work, but when I submit the form the only thing I get back is the object name (SerialNumbers) as the key.
I want to be able to get the selected item from the dropdown list and pass this to the FormCollection in the Httpost of the Index action. For the life of me, I cannot get it to work!
I am expecting to see a key called 'CustomersDdl' and it's value. For example, if I had a dropdown full of countries and I pick England, I am expecting to see a value come back in the FormCollection saying England.
What am I doing wrong?
The value to postback is depending on how you create "SelectListItem", in your case it is in the method "GetAllSerials()"
vm.SerialNumbers = serialNumbers.Select(serial => new SelectListItem
{
Selected = serial.id == vm.SelectedSerial ? true : false,
Text = serial.Name,
Value = serial.Name
}).ToList();
I am a new to MVC and still learning! I am trying to create a very basic App in my web which allows users to convert money value according to their preference. I made the web APi and was successful to call the service to my forms. However, in my controller I managed to get the currencies (names) to the index view, but cannot post the form back once entering a value in the text box to generate the partial view! What am I doing wrong in my codes?!
Currency Controller
namespace MVC_ATM.Controllers
{
public class CurrencyController : Controller
{
[HttpGet]
// GET: Currency
public ActionResult Index()
{
CurrenciesClient Cur = new CurrenciesClient();
var listCurrency = Cur.findAll();
SelectList list = new SelectList(listCurrency,"Id", "CurrencyName");
ViewBag.listCurrencies = list;
return View();
}
[HttpPost]
public ActionResult Index(Currencies cur)
{
if (!ModelState.IsValid)
{
string errors = string.Join("<br />", ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => x.ErrorMessage));
return new ContentResult { Content = errors };
var rate = Convert.ToDecimal(cur.ConversionRate);
if (cur.CurrencyName == cur.CurrencyName)
{
ModelState.AddModelError("CurrencyCountry", "Can't make the conversion for the same value");
}
else if (cur.CurrencyName != cur.CurrencyName)
{
foreach (var currency in cur.CurrencyName)
{
ViewBag.Theresult = rate * cur.Value;
}
return PartialView("_CurrencyValue");
}
}
return View();
}
}
}
Currencies Model
namespace Project.Model
{
public class Currencies
{
public int Id { get; set; }
public string CurrencyName { get; set; }
public string CurrencyCountry {get; set;}
public decimal Value { get; set; }
public string ConversionRate { get; set; }
}
}
Index View
#model Project.Model.Currencies
#{
ViewBag.Title = "Index";
}
<h2>Currency</h2>
<body>
<div class="converter">
Convert: #Html.TextBoxFor(m => m.ConversionRate, new { #size = "5" })
<div class="form-group">
#Html.Label("Convert from", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownList("Currency List", ViewBag.listCurrencies as SelectList, "Please Select a currency")
</div>
</div>
<div class="form-group">
#Html.Label("Convert to", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownList("Currency List", ViewBag.listCurrencies as SelectList, "Please Select a currency")
</div>
</div>
<div>
<button type="submit" class="btn btn-primary">Convert</button>
</div>
</div>
</body>
Couple of things to notice, is the POST action and missing form tag in the view . You created a POST action that accepts Currencies model but the form doesn't post that. Only ConversionRate will bind to the model. To get the "Currency From" and "Currency To" and the "Conversion Rate" you will require a different approach/small changes.
ConversionModel.cs a new Model for index page that will capture your required fields.
public class ConversionModel
{
[Required]//decimal would be better but up to you requirement
public decimal ConversionRate { get; set; }
[Required]
public int FromCurrencyId {get;set;}
public SelectList FromCurrencies {get;set;}
[Required]
public int ToCurrencyId {get;set;}
public SelectList ToCurrencies {get;set;}
}
Get: while there is nothing wrong with what you've done, lets use a model approach and tightly bind it.
public ActionResult Index()
{
CurrenciesClient Cur = new CurrenciesClient();
var listCurrency = Cur.findAll();
ConversionModel model = new ConversionModel();
model.FromCurrencies = new SelectList(listCurrency,"Id", "CurrencyName");
model.ToCurrencies = new SelectList(listCurrency,"Id", "CurrencyName");
return View(model);
}
Post: Important thing here to notice is the SelectList will not be posted back. Only the ConversionRate, FromCurrencyId and ToCurrencyId are sent back not the Lists. If error occurs you will need to rebuild the lists and send it back in the model.
[HttpPost]
public ActionResult Index(ConversionModel curModel)
{
if(ModelState.IsValid)
{
if(curModel.FromCurrencyId ==curModel.ToCurrencyId)
{
//do something if same currecnies and return.
}
else
{
//Get the currencyList with rates from db
//use currency ToCurrencyId and FromCurrencyId to fetch the 2 currencies
// perform conversion with curModel.ConversionRate with existing logic
}
}
//Don'f forget to rebuild the Select Lists...
return View(curModel);
}
View:
#model Project.Model.ConversionModel
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("Index", "Currency", FormMethod.Post)
{
#Html.TextBoxFor(m => m.ConversionRate, new { #size = "5" })
#* Please check the syntax *#
#Html.DropDownListFor(m => m.FromCurrencyId , Model.FromCurrencies as SelectList)
#Html.DropDownListFor(m => m.ToCurrencyId , Model.ToCurrencies as SelectList)
<button type="submit" class="btn btn-primary">Convert</button>
}
Not a CUT_COPY_PASTE. please do check for errors if any. It is only an approach.
ajax POST probably the next thing to learn... Let us know.
You need to put your items inside a form like this:
#using (Html.BeginForm("Index", "Currency", FormMethod.Post)
{
// Your form items
}
I have flights timetable - Schedule view with list of flights
Where I just return View and have some filters and sorting.
Here is part of my view:
#model IEnumerable<AirPortIS.Models.Flight>
<div class="page-header">
<h3>Flights</h3>
</div>
<div id="modDialog" class="modal fade">
<div id="dialogContent" class="modal-dialog"></div>
</div>
<table class="table-bordered table-condensed">
<thead>
<tr>
<th>Flight №</th>
<th>Departure</th>
<th>Destination</th>
<th>#Html.ActionLink("Day", "Schedule", new { sort = ViewBag.SortDay, company = ViewBag.FiltrC, destination = ViewBag.FiltrD })</th>
<th>Departure Time</th>
<th>Arrival Time</th>
<th>Company</th>
<th>#Html.ActionLink("Seats", "Schedule", new { sort = ViewBag.SortSeats, company = ViewBag.FiltrC, destination = ViewBag.FiltrD })</th>
<th>#Html.ActionLink("Cost", "Schedule", new { sort = ViewBag.SortCost, company = ViewBag.FiltrC, destination = ViewBag.FiltrD })</th>
<th>Book ticket</th>
</tr>
</thead>
#foreach (var f in Model)
{
<tr>
<td>#Html.ActionLink(f.FlightId.ToString(), "FlightDetails", new { id = f.FlightId }, new {#class = "flItem" } )</td>
<td>#f.Departure</td>
<td>#f.Destination</td>
<td>#f.Day</td>
<td>#f.DepartureTime</td>
<td>#f.ArrivalTime</td>
<td>#f.Company.Name</td>
<td>#f.Seats</td>
<td>#f.Cost</td>
<td>#Html.ActionLink("Link for booking ticket")</td>
</tr>
}
</table>
I need to do that by clicking on a button "Book ticket" user is getting a page where dropdownlist have a preset value of FlightId.
For example we have a flight №1 and a link "Book ticket",so when user goes the booking ticket page he gets a droptdownlist with preselected value "1"
Here is my ticket Model
public class Tickets
{
public int Id { get; set; }
public int TicketId { get; set; }
public Flight Flight { get; set; }
public string Seat {get;set; }
public string Passenger { get; set; }
public int Flightid { get; set; }
public string Status { get; set; }
}
And part of TicketsController:
public class TicketsController : Controller
{
private readonly AirportContext _db = new AirportContext();
[Authorize]
public ActionResult Tickets()
{
var ticket = _db.Tickets.Include(t => t.Flight);
return View(ticket);
}
[HttpGet]
public ActionResult BookTicket()
{
IEnumerable<SelectListItem> statusList = new SelectList(new List<string> { "Book", "Buy" });
IEnumerable<SelectListItem> flights = new SelectList(_db.Flights.ToList(), "FlightId", "FlightId");
ViewData["flights"] = flights;
ViewData["statusList"] = statusList;
return View();
}
[HttpPost]
public ActionResult BookTicket(Tickets ticket)
{
IEnumerable<SelectListItem> statusList = new SelectList(new List<string> { "Book", "Buy" });
IEnumerable<SelectListItem> flights = new SelectList(_db.Flights.ToList(), "FlightId", "FlightId");
ViewData["flights"] = flights;
ViewData["statusList"] = statusList;
foreach (var c in _db.Tickets.ToList())
{
if ((_db.Tickets.ToList().Exists(x => c.TicketId == ticket.TicketId)) || (ticket.TicketId <= 0))
{
ModelState.AddModelError("TicketId", "Wrong ticket id");
}
if ((_db.Tickets.ToList().Exists(x => c.Seat == ticket.Seat)) && (_db.Tickets.ToList().Exists(x => c.Flightid == ticket.Flightid))
&& (_db.Tickets.ToList().Exists(x => c.TicketId == ticket.TicketId)))
{
ModelState.AddModelError("Seat", "The seat is unavailable");
}
if (_db.Tickets.ToList().Exists(x => c.Passenger == ticket.Passenger))
{
ModelState.AddModelError("Passenger", "The ticket has already bought");
}
}
if (ModelState.IsValid)
{
_db.Tickets.Add(ticket);
_db.SaveChanges();
return RedirectToAction("Tickets");
}
else return View(ticket);
}
And my BookTikcet View:
#model AirPortIS.Models.Tickets
#{
ViewBag.Title = "Book ticket";
}
<h2>Book ticket:</h2>
<form class="form-inline" method="post">
<div>
#Html.ValidationSummary()
</div>
<div class="form-group col-md-2">
Ticket №<br/>
#Html.EditorFor(model => Model.TicketId)
</div>
<div class="form-group col-md-1">
Flight №<br />
#Html.DropDownListFor(model => Model.Flightid, ViewData["flights"] as IEnumerable<SelectListItem>)
</div>
<div class="form-group col-md-2">
Место<br />
#Html.EditorFor(model => Model.Seat)
</div>
<div class="form-group col-md-2">
Passenger Name<br />
#Html.EditorFor(model => Model.Passenger)
</div>
<div class="form-group col-md-2">
Status<br />
#Html.DropDownListFor(model => Model.Status, ViewData["statusList"] as IEnumerable<SelectListItem>)
</div>
<div>
<input class="btn-success" type="submit" value="Book Ticket"/>
</div>
</form>
<div>
<form method="get" action="Tickets">
<button class="btn-danger" type="submit">Cancel</button>
</form>
</div>
I have no idea how to do it,so this whole code above just a standart code for creating a new ticket.
How I should modify code or add something to have this (For example we have a flight №1 and a link "Book ticket",so when user goes the booking ticket page he gets a droptdownlist with preselected value "1",for flight №2 on a page dropdownlist has a preselected value "2" for FlightId.
Hope that my question is clear,sorry if something is wrong written or not quite clear.
You need to pass the value of FlightId as a route (or query string) value to the BookTicket method. You link should be
#Html.ActionLink("Book ticket", "BookTicket", new { id = f.FlightId })
and modify the method to
[HttpGet]
public ActionResult BookTicket(int ID)
{
... // set you SelectLists as above
// Initialize your model and set the Flightid property
var model = new Tickets()
{
Flightid = ID
};
return View(model); // return the model to the view
}
Your dropdownlist will now have the option identified by Flightid selected when you first generate the view.
Note. I recommend you use a view model rather than your Tickets data model which will contain properties IEnumerable<SelectListItem> Flights and IEnumerable<SelectListItem> StatusList rather than using ViewData so that your view are strongly typed using
#Html.DropDownListFor(m => m.Flightid, Model.Flights)
You should also consider refactoring the code to populate the SelectLists into a private method so that you do not repeat code, for example
private void ConfigureViewModel(TicketVM model)
{
model.Flights = new SelectList(...);
model.StatusList = new SelectList(...);
}
Note also that it is a waste of resources to be calling your database to get the SelectList's in the POST method if ModelState is valid. Your code should be
if (!ModelState.IsValid)
{
ConfigureViewModel(model); // only necessary if you need to return the view
return View(model);
}
// save and redirect
Side note: It's unclear why you actually need a dropdownlist for Flightid in the BookTicket view. The user has already selected the flight so why are you giving the option to change it? It might be more appropriate to just render the Flightid as a hidden or readonly input so its submitted back to the POST method.
In my MVC4 project I failed to get my DropDownList data on edit controller.
My UI syntax is bellow:
<div class="form-group">
#Html.HiddenFor(model => model.School.SchoolID)
#Html.LabelFor(model => model.School.SchoolName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.School.SchoolName)
#Html.ValidationMessageFor(model => model.School.SchoolName)
</div>
</div>
<div class="form-group">
#Html.HiddenFor(model => model.StudentCLass.ID)
#Html.LabelFor(model => model.StudentCLass.ClassName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.StudentCLass.ID, #ViewBag.StudentCLassList as SelectList,"Select Class")
#Html.ValidationMessageFor(model => model.StudentCLass.ID)
</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>
To fill the DropDownList I use bellow syntax:
public ActionResult Edit(int Id)
{
using (DB = new StudentContext())
{
var result = DB.Students.FirstOrDefault(c => c.ID == Id);
ViewBag.StudentCLassList = new SelectList(DB.StudentClasses
.Select(sc => new ViewModelClass
{
ID = sc.ID,
ClassName = sc.ClassName
}).ToList(), "ID", "ClassName");
return View(StudentInfo(result));
}
}
After click the submit button I can not get DropDownList value on my controller action.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ViewModel.ViewModelStudents student)
{
var tempResult = student.StudentCLass.ID;
//return RedirectToAction("Index");
// return View(student);
}
Model structure
public partial class StudentClass
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public StudentClass()
{
Students = new HashSet<Student>();
}
public int ID { get; set; }
[StringLength(100)]
public string ClassName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Student> Students { get; set; }
}
MVC Doen't post the DropDown list back to the Controller, You will have to populate dropdown list again in POST method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ViewModel.ViewModelStudents student)
{
var tempResult = student.StudentCLass.ID;
ViewBag.StudentCLassList = new SelectList(DB.StudentClasses
.Select(sc => new ViewModelClass
{
ID = sc.ID,
ClassName = sc.ClassName
}).ToList(), "ID", "ClassName");
return RedirectToAction("Index");
}
You could write the Dropdown list code in a function, if you don't want to read this dropdown list from DB evertime you can save it to Session[]:
public void PopulateDropDownList(){
var items = Session["MyDropDown"] != null ? (SelectList)Session["MyDropDown"] : null;
if(items ! null) {ViewBag.StudentCLassList; return;}
items = new SelectList(DB.StudentClasses
.Select(sc => new ViewModelClass
{
ID = sc.ID,
ClassName = sc.ClassName
}).ToList(), "ID", "ClassName");
Session["MyDropDown"] = ViewBag.StudentCLassList = items;
}
Note: If you save the DropDown list in Session, you don't have write it to ViewBag, but you can access it directly in View.
And call this method in Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ViewModel.ViewModelStudents student)
{
var tempResult = student.StudentCLass.ID;
PopulateDropDownList();
return RedirectToAction("Index");
}
EDIT
I don't understand you are saying that you want the DropDown to be selected but you are Redirecting to `Index'.
If you do:
return View(student);
Instead of
return RedirectToAction("Index");
return RedirectToAction("Index"); will redirect you to Index page, refreshing your webpage.
EDIT 2:
I just noticed you have
#Html.HiddenFor(model => model.StudentCLass.ID)
MVC is posting the Value from this Hidden Back to the Controller. Try removing this,
The thing is that you have two controls with the same id
#Html.DropDownListFor(model => model.StudentCLass.ID
AND
#Html.HiddenFor(model => model.StudentCLass.ID)
I think you want something like this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ViewModel.ViewModelStudents student)
{
if (ModelState.IsValid)
{
// save changes and redirect
return RedirectToAction("Index");
}
else
{
using (DB = new StudentContext())
{
ViewBag.StudentCLassList = new SelectList(DB.StudentClasses.ToList(), "ID", "ClassName");
}
return View(student);
}
}
The framework will take care of preserving selected values across requests.