DropDownListFor - need help defining "SelectedValue" property - asp.net-mvc

I need help understanding how to set the SelectedValue property in HTML.DropDownListFor.
Here's what I have so far:
In another part of the model, MA is an int that is stored on the database.
In the Model:
public IList<SelectListItem> SelectListMA(int MA)
{
IList < SelectListItem > List = new List<SelectListItem>();
SelectListItem Item;
for(int i = 1; i <= 9; i++)
{
Item = new SelectListItem
{
Value = i.ToString(),
Text = i.ToString(),
Selected = i == MA
};
List.Add(Item);
}
return List;
}
In the controller:
ViewBag.MA = _Repository.SelectListMA(5);
And finally, in the View:
#Html.DropDownListFor(model => model.MA, new SelectList(ViewBag.MA, dataValueField: "Value", dataTextField: "Text"))
In the View the dropdown displays fine, however the default value is not being set and I am using the model to pass the original model for editing to View hence using ViewBag
Edit: Further details Requested - this is the full Controller that this belongs to.
private readonly IRacesRepos _RaceRepository;
public BaseTeamsController(IRacesRepos _Repository)
{
_RaceRepository = _Repository;
}
//sets the Model to the repository
public BaseTeamsController() : this(new ModelRaces()) { }
public ActionResult BEditPlayer(int ID)
{
Races_Players SelectedPlayer = _RaceRepository.GetPlayerBase(ID);
ViewBag.MA = _RaceRepository.SelectListMA(SelectedPlayer.MA);
ViewBag.ST = _RaceRepository.SelectListST(SelectedPlayer.ST);
ViewBag.AG = _RaceRepository.SelectListAG(SelectedPlayer.AG);
ViewBag.PA = _RaceRepository.SelectListPA((int)SelectedPlayer.PA);
ViewBag.AV = _RaceRepository.SelectListAV(SelectedPlayer.AV);
ViewBag.Race = _RaceRepository.GetRaceBase(SelectedPlayer.RaceID);
return View(SelectedPlayer);
}
And I am using MVC version 5, and ModelRaces is the name of the model that contains the code, MA is an int in the model from the database.
Full View
#model BB2020MVC.Models.Races_Players
#{
ViewBag.Title = "Add Player to " + ViewBag.RaceName;
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Add Player to #ViewBag.RaceName</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.PlayerID)
#Html.HiddenFor(model => model.RaceID)
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10 focus">
#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.MA, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.MA, new SelectList(ViewBag.MA, dataTextField: "Text", dataValueField:"Value") , new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MA, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ST, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.ST, new SelectList(ViewBag.ST, dataTextField: "Text", dataValueField: "Value"), new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ST, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AG, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.AG, new SelectList(ViewBag.AG, dataTextField: "Text", dataValueField: "Value"), new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.AG, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PA, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.PA, new SelectList(ViewBag.PA, dataTextField: "Text", dataValueField: "Value") ,new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PA, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AV, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.AV, new SelectList(ViewBag.AV, dataTextField: "Text", dataValueField: "Value") ,new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.AV, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Cost, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Cost, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Cost, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MaxQTY, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MaxQTY, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MaxQTY, "", 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("Cancel", "ViewRace", new { ID = Model.RaceID })
</div>
Edit: Been doing a bit of testing and reading, issue seems to be that the view is not selecting the selected value of model => model.MA yet the value is not null on editing so any value that has been selected by SelectListItem or SelectList is ignored.
Also passing any value into selectedValue other than a number or word (eg "1" or "Word", not a variable of type int or string) causes the item to not be selected.
Doesn't fix the issue but an interesting point.

Try this syntax:
in the view
#Html.DropDownListFor(model => model.MA, ViewBag.MA,"Select One", new { htmlAttributes = new { #class = "form-control" } })
in repository:
public SelectList SelectListMA(int MA)
{
var List = new List<SelectListItem>();
for(int i = 1; i <= 9; i++)
{
List.Add(new SelectListItem
{
Value = i.ToString(),
Text = i.ToString(),
});
}
return new SelectList(list, "Value", "Text",MA);
}
But you don't need to convert to List of SelectListItem your existed lists.
Just use retun new SelectList(yourlist, "yourvalueproperty", "yourtextproperty",);

The answer to this one lies between the keyboard and the screen.
Let me explain:
In the additional testing I had erroneously changed _RaceRepository.GetPlayerBase(ID) to another function that generates a new base for the record. (an impromptu Mutation Test!)
This meant every time I was trying to edit the player, I was passing the default value of "1 to the view and upon submission edited a model that never existed in the first place.
Upon setting the correct function, I was getting the correct values and thus the setting of the selected value sorted itself out.
I will however thank Sergey for having a look and trying to assist, and providing a better way of providing a SelectList (A better version would be to use a ViewModel, that will have to be used for another part).
So for those that are interested, here is the code that solves this issue:
From the Model:
public SelectList SelectListMA()
{
IList<SelectListItem> List = new List<SelectListItem>();
SelectListItem Item;
for(int i = 1; i <=9; i++)
{
Item = new SelectListItem()
{
Value = i.ToString(),
Text = i.ToString()
};
List.Add(Item);
}
return new SelectList(List,"Value","Text");
}
From the Controller:
public ActionResult BEditPlayer(int ID)
{
Races_Players SelectedPlayer = _RaceRepository.GetPlayerBase(ID);
ViewBag.MASelect = _RaceRepository.SelectListMA();
ViewBag.STSelect = _RaceRepository.SelectListST();
ViewBag.AGSelect = _RaceRepository.SelectListAG();
ViewBag.PASelect = _RaceRepository.SelectListPA();
ViewBag.AVSelect = _RaceRepository.SelectListAV();
return View(SelectedPlayer);
}
From the View: - as SelectList is to stop errors happening as the code is built
#Html.DropDownListFor(model => model.MA, ViewBag.MASelect as SelectList, "Select One")
Also, for any new programmers as per the research and testing, SelectList and SelectListItem have SelectedValue and Selected respectively for selecting Default values.
SelectedValue can be any object that identifies the primary key of the list or a new default value of the list (eg integer for a value already in the list, or a string for a default value of null).
Selected, however, is a boolean (ie true or false) that selects the value of the list. You only need to use one or the other.
Remember - if the value is passed from the controller to the view as the value in model => model.[Variable] then the value will be set to the value passed, not to the value set by SelectedValue or Selected.

Related

HiddenInput not working while render on view MVC 5

I have used HiddenInput(DisplayValue = false) like:
[HiddenInput(DisplayValue = false)]
[DisplayName("Updated By")]
public string Updatedby { get; set; }
but it's still rendering as EditorFor
<div class="form-group">
#Html.LabelFor(model => model.Updatedby, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Updatedby, new { htmlAttributes = new { #class = "form-control" } }) #Html.ValidationMessageFor(model => model.Updatedby, "", new { #class = "text-danger" })
</div>
</div>
I want to render it as hidden field. How can I do that? Thank you.
You can use
#Html.HiddenFor(m=>m.Updatedbynew ,new { #class = "form-control" })
for rendering a hidden model-binded field in DOM.

Passing a viewbag to a #Dropdownlist

I'm trying to pass view bag to a DropDownList but is not working.
Dropdownlist Error
view
<div class="form-group">
#Html.LabelFor(model => model.BanhoTosaId, "BanhoTosaId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("TransporteId", ViewBag.BanhoTosaId, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BanhoTosaId, "", new { #class = "text-danger" })
</div>
</div>
Controller
// GET: AgendaBTs/Create
public ActionResult Create(int id, int pet)
{
ViewBag.BanhoTosaId = new SelectList(db.BanhoTosas, "BanhoTosaId", "Tipo");
ViewBag.ClienteId = new SelectList(db.Clientes, "ClienteId", "Nome", id);
ViewBag.PetId = new SelectList(db.Pets, "PetId", "PetNome", pet);
ViewBag.TransporteId = new SelectList(db.Transportes, "TransporteId", "Tipo");
if (ViewBag.BanhoTosaId != null && ViewBag.SelectedValue != null)
{
BanhoTosa BT = db.BanhoTosas.Find(ViewBag.BanhoTosaId);
Transporte TS = db.Transportes.Find(ViewBag.TransporteId);
decimal valorSoma = BT.Valor + TS.Valor;
ViewBag.Total = valorSoma;
}
else
{
ViewBag.Total = 0;
}
return View();
}
If I let the dropdown this way #Html.DropDownList("TransporteId",null, htm....
the if in the controller you throw the else method.
How can i do to solve this?
you first need to make a list from data you wanna fill list by it like that :
List<Category> CatList = db.Categories.ToList();
and then use a ViewBag :
ViewBag.CategoriesList = new SelectList(CatList, "CategoryID", "CategoryName");
after that you will going to view and write:
<div class="form-group" style="margin-left:85px">
<div class="col-md-10">
#Html.DropDownListFor(model => model.CategoryID, ViewBag.CategoriesList as SelectList,
"Select Category", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CategoryID, "", new { #class = "text-danger" })
</div>
</div>
this example from project i worked on it before
You need to cast the ViewBag.BanhoTosaId:
#Html.DropDownList("TransporteId", (List<SelectList>) ViewBag.BanhoTosaId, htmlAttributes: new { #class = "form-control" })
OR
In your Create action replace this:
ViewBag.TransporteId = new SelectList(db.Transportes, "TransporteId", "Tipo");
By
ViewBag.TransporteId = db.Transportes;
Add then in your razor view:
#Html.DropDownList("TransporteId", new SelectList(ViewBag.TransporteId , "TransporteId", "Tipo"))
Replace
#Html.DropDownList("TransporteId", ViewBag.BanhoTosaId, htmlAttributes: new { #class = "form-control" })
with
#Html.DropDownList("TransporteId", (IEnumerable<SelectListItem>)ViewBag.BanhoTosaId,null, new { #class = "form-control" })

How could I store an "id" (urlparameter.optional) through a textboxfor()

I'm trying to store an id from url in a textboxfor(), but I don't obtain the result. When i put "id" in a textbox, I obtain the correct result. Instead, in a textboxfor(model=> model.IDCantiere,new{#value="id"}). It doesn't run; please help me, I've attached the code fragments:
Controller.cs
// GET: CantiereOres/Create
public ActionResult Create(int id)
{
ViewBag.id = id;
//ViewBag.IdCantiere = new SelectList(db.Cantieres, "IdCantiere", "IdCantiere");
ViewBag.IdPersona = new SelectList(db.CantierePersones, "IdPersona", "Persona");
return View();
}
// POST: CantiereOres/Create
// Per proteggere da attacchi di overposting, abilitare le proprietà a cui eseguire il binding.
// Per ulteriori dettagli, vedere https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "IdOre,IdCantiere,IdPersona,Ore,datetime")] CantiereOre cantiereOre)
{
if (ModelState.IsValid)
{
db.CantiereOres.Add(cantiereOre);
db.SaveChanges();
return RedirectToAction("details", "Cantieres", new { id = cantiereOre.IdCantiere });
}
ViewBag.IdCantiere = new SelectList(db.Cantieres, "IdCantiere", "IdCantiere", cantiereOre.IdCantiere);
ViewBag.IdPersona = new SelectList(db.CantierePersones, "IdPersona", "Persona", cantiereOre.IdPersona);
return View(cantiereOre);
}
View.cshtml:
#model archeagroup.Models.CantiereOre
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.TextBox("id")
<div class="form-horizontal">
<h4>CantiereOre</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.IdCantiere, "IdCantiere", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model=>model.IdCantiere, new {#value ="id", #class = "form-control" } )
#*#Html.EditorFor(model => model.IdCantiere, new { htmlAttributes = new { #class = "form-control" } })*#
#Html.ValidationMessageFor(model => model.IdCantiere, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IdPersona, "IdPersona", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("IdPersona", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.IdPersona, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Ore, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Ore, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Ore, "", 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", "Details", "Cantieres")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
If you want 2441 to be in this textbox right?
#Html.TextBoxFor(model=>model.IdCantiere, new {#value ="id", #class = "form-control" } )
Then in your controller, instead of this:
ViewBag.id = id;
Do this:
Model.IdCantiere = id;
And change your textbox to:
#Html.TextBoxFor(model=>model.IdCantiere, new { #class = "form-control" })
Which will put (from your screenshot) 2441 in the textbox you indicated.
EDIT: So you need to return an instance of archeagroup.Models.CantiereOre from your controller Create method:
public ActionResult Create(int id)
{
var model = new acheagroup.Models.CantiereOre();
model.IdCantiere = id;
model... //other assignments - use this instead of ViewBag
return View(model);
}
With this the above code will work since it will be fed from the model.

How get List<~> fron View to Controller MVC [duplicate]

This question already has answers here:
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 6 years ago.
I have three related tables
Tables
In the table "SelectedMaterial" need to enter the values in the column "CountMaterial" (initially there null)
Values
For this in controller I have POST and GET methods
public ActionResult EditCountOfMaterial(int id)
{
var selectedmaterial = db.SelectedMaterials.Where(m => m.CardId == id).ToList();
return View(selectedmaterial);
}
[HttpPost]
public ActionResult EditCountOfMaterial(List<SelectedMaterial> material)
{
//material = db.SelectedMaterials.Where(m => m.CardId == 3).ToList();
for (int i = 0; i < material.Count; i++)
{
//material[i] = db.SelectedMaterials.Where(m => m.CardId == 3).First();
db.Entry(material[i]).State = EntityState.Modified;
db.SaveChanges();
}
return RedirectToAction("Index");
}
I also have a view
#model IEnumerable<AccountingPlusProject.Models.SelectedMaterial>
#{
ViewBag.Title = "EditCountOfMaterial";
}
<h2>EditCountOfMaterial</h2>
#using (Html.BeginForm())
{
foreach (var item in Model)
{
#item.ReferenceMaterial.NameMaterial
<div class="form-group">
#Html.LabelFor(model => item.CountMaterial, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => item.CountMaterial, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => item.CountMaterial, "", 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>
}
But from the view comes null values. How to pass list from View with a value?
Something like Below. The Posted back values have to be in array form.
#using (Html.BeginForm())
{
foreach (var item in Model)
{
var count= 0;
#item.ReferenceMaterial.NameMaterial
<div class="form-group">
#Html.LabelFor(model => item.CountMaterial, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => item.CountMaterial, new { htmlAttributes = new { #class = "form-control", #name="SelectedMaterial[" + count.ToString() + "].CountMaterial"} })
#Html.ValidationMessageFor(model => item.CountMaterial, "", new { #class = "text-danger" })
</div>
</div>
count+=1;
}
}

Why DefaultModelBinder doesn't bind route value ID from URL

ASP.NET MVC
In short:
I have a get action and a post action
when I type in browser localhost:port/Employee/Edit/1 I call get action, so in URL I have this whole url string. When I press submit button, in post action defaultmodelbinder doesnt bind id from URL!!!! I HAVE TO ADD HIDDEN FIELD for id. But why? I also have delete action (post), that gets id too, and I dont need to add hidden field for id. why?
More specifically:
I have the model:
public class EmployeeViewModel
{
public Int32 EmployeeId { get; set; }
public String Name { get; set; }
public String Phone { get; set; }
public String Email { get; set; }
public String Other { get; set; }
}
And 2 actions
public ActionResult Edit(int id)
{
try
{
EmployeeViewModel model;
using (var dbSession = NHibernateHelper.OpenSession())
{
var employee = dbSession.Query<Employee>().First(e => e.EmployeeId == id && e.ExpireDate==null);
model = new EmployeeViewModel(employee);
}
return View(model);
}
catch
{
return View("Error");
}
}
[HttpPost]
public ActionResult Edit(EmployeeViewModel model)
{
try
{
using (var dbSession=NHibernateHelper.OpenSession())
using (var transaction=dbSession.BeginTransaction())
{
var employee = model.ToEmployee();
dbSession.Merge(employee);
transaction.Commit();
}
return RedirectToAction("Index");
}
catch
{
return View("Error");
}
}
And 1 View (HERE I HAVE TO WRITE THIS LINE #Html.HiddenFor(model => model.EmployeeId) )
#using (Html.BeginForm()){
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.HiddenFor(model => model.EmployeeId)
#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.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.Other, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Other, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Other, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Сохранить" class="btn btn-default" />
</div>
</div>
</div>}
Because the parameter in the method is named id and the property in
your model is named EmployeeId They are not the same. And if you
change the model property to Id it will be bound
Thanks, Stephen Muecke

Resources