I'm trying to get an integer out of a listitem.
i first collected the items to put in the dropdownlist and then i try to take the integer out of the items
It worked before(got a nice string with interests in database), but more often than not, i get an error for trying to make an integer out of a listitem
I would like to solve this so it works 100% of the time so it doesn't look like an incomplete project when i present this.
<div class="form-group">
#Html.LabelFor(m => m.InteresseLijst1, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.Interesse1, Model.InteresseLijst1)
</div>
</div>
these are the used properties from my viewmodel
[Display(Name = "Interesse 1")]
public SelectList InteresseLijst1 { get; set; }
[Display(Name = "Interesse 2")]
public SelectList InteresseLijst2 { get; set; }
public int Interesse1 { get; set; }
public int Interesse2 { get; set; }
public string Interesses { get; set; }
this is my Get-action to register where i make my selectlists
public ActionResult Register()
{
RegisterViewModel rvm = new RegisterViewModel();
List<Categorie> categorielijst = CategoryRepository.GetCategories();
rvm.InteresseLijst1 = new SelectList(categorielijst, "CategoryId", "CategoryName");
rvm.InteresseLijst2 = new SelectList(categorielijst, "CategoryId", "CategoryName");
return View(rvm);
}
and this is my post where i use the integers collected from the selectlist.
I convert to json to keep it in my database for further comparison on other parts of the site.
#region verschillend
if(model.Interesse1 != model.Interesse2)
{
int[] interesses = new int[2] { model.Interesse1, model.Interesse2 };
string sInteresses = JsonConvert.SerializeObject(interesses);
model.Interesses = sInteresses;
//other code
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
#endregion
With a bit of a workaround, i managed to get rid of the error. I changed the way the items are displayed by adding properties to items in a list. Then i collect the values of the properties in my controller with Request.Form["propertyname"] and it worked
Related
I'm struggling with dropdownlist tried several methods online and all failed will show the methods that I tried.
Objective
Create a Reciept with date,reference... & country. Country is Required and should be a dropdownlist.
So the Table for Reciept("ID, Name, Date, Address, City, CountryList).
RecieptModel
public class TransactionModel
{
public int ID { get; set; }
public int Name{ get; set; }
public DateTime Date { get; set; }
public string Address { get; set;}
public string City { get; set; }
public CountryList CountryList { get; set; }
}
public class ApplicationDbContext : DbContext
{
public DbSet<RecieptModel> Reciepts { get; set;}
public DbSet<CountryList> coutryList { get; set; }
}
CountryList
public class CountryList
{
public byte Id { get; set; }
public enum Country
{
Germany,
US,
UK
}
}
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Name,Date,City,CountryList")] Reciepts reciepts)
{
if (ModelState.IsValid)
{
db.Reciepts.Add(reciepts);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(reciepts);
}
View
<div class="form-group">
#Html.LabelFor(model => model.CountryList, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.CountryList)
#Html.ValidationMessageFor(model => model.CountryList)
</div>
</div>
This failed I looked for several examples I'm trying to do it without the use of javascript. In the End I just want to learn how to implement a Dropdownlist & save it to the database allot of the methods that I tried to implement failed in MVC5.
I would sugest you to add a html extension method that implement dropdownlist for a generic enumarator. Take a look at this answer.
There is slightly change in your view where you bind the Country
this is actually you write
#Html.EnumDropDownListFor(model => model.CountryList)
Change is need to add name property in your country list (it must be ID that is your taken in your model) , so it must be like this to maintain country list value
#Html.DropDownListFor(model => model.CountryList.Id, new SelectList(model => model.CountryList)
Becouse every HTML control need unique indentifier
I would like to ask is there any way to set an automatic DateTime.Now value for properties ENTRY_DATE and AUDIT_TIME in the Create() HttpPost method? The form is created and it works fine. If the DateTime is inserted manually. But, it won't work if I set an automatic value and would run into a
"One or more validation Error's"..
This is my model (I don't understand how to make a viewmodel) :
public partial class TRRESPONDENT
{
public TRRESPONDENT()
{
this.TRFOLLOWUPRESPONDENTs = new HashSet<TRFOLLOWUPRESPONDENT>();
}
[Required(ErrorMessage = "Respondent ID is required!")]
[Display(Name = "Respondent ID")]
public string RESPONDENT_ID { get; set; }
[Required(ErrorMessage = "Please select a BINUS Center!")]
[Display(Name = "Binus Center")]
public string BC_ID { get; set; }
[Required(ErrorMessage = "Name cannot be empty!")]
[Display(Name = "Name")]
[StringLength(100,ErrorMessage = "Name length cannot be more than 100 characters!")]
public string FULL_NAME { get; set; }
.... // more properties
[Required(ErrorMessage = "Please pick a City Location!")]
[Display(Name = "City")]
public int CITY_ID { get; set; }
// The following 2 properties need to be set
[Display(Name = "Entry Date")]
public DateTime ENTRY_DATE { get; set; }
public DateTime AUDIT_TIME { get; set; }
....
public virtual LTCITY LTCITY { get; set; }
public virtual LTSOURCERESPONDENT LTSOURCERESPONDENT { get; set; }
public virtual MSBINUSCENTER MSBINUSCENTER { get; set; }
public virtual ICollection<TRFOLLOWUPRESPONDENT> TRFOLLOWUPRESPONDENTs { get; set; }
}
This is my view
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.LabelFor(model => model.RESPONDENT_ID)
#Html.EditorFor(model => model.RESPONDENT_ID)
#Html.ValidationMessageFor(model => model.RESPONDENT_ID)
#Html.LabelFor(model => model.BC_ID, "Binus Center")
#Html.DropDownList("BC_ID", null)
#Html.ValidationMessageFor(model => model.BC_ID)
#Html.LabelFor(model => model.FULL_NAME)
#Html.EditorFor(model => model.FULL_NAME)
#Html.ValidationMessageFor(model => model.FULL_NAME)
.... // more form controls
#Html.LabelFor(model => model.CITY_ID, "City")
#Html.DropDownList("CITY_ID", null)
#Html.ValidationMessageFor(model => model.CITY_ID)
#Html.HiddenFor(model => model.ENTRY_DATE)
#Html.HiddenFor(model => model.AUDIT_TIME)
<input type="submit" value="Create" class="btn btn-default" />
}
This is my controller :
public class RespondentController : Controller
{
private RespondentBINUSEntities db = new RespondentBINUSEntities();
public ActionResult Create()
{
ViewBag.CITY_ID = new SelectList(db.LTCITies, "CITY_ID", "CITY_NAME", 1);
var entry = new Models.TRRESPONDENT
{
ENTRY_DATE = DateTime.Now,
AUDIT_TIME = DateTime.Now,
};
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "RESPONDENT_ID,BC_ID,BINUSIAN_ID,FULL_NAME,EMAIL,PHONE_NUMBER,ADDRESS,CITY_ID,ZIP_CODE,SOURCE_ID,ENTRY_DATE,PACKAGE,AUDIT_USER_NAME,AUDIT_TIME,AUDIT_ACTIVITY")] TRRESPONDENT tRRESPONDENT)
{
if (ModelState.IsValid)
{
db.TRRESPONDENTs.Add(tRRESPONDENT);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CITY_ID = new SelectList(db.LTCITies, "CITY_ID", "CITY_NAME", tRRESPONDENT.CITY_ID);
return View(tRRESPONDENT);
}
}
You have not stated the details of the error message, but no doubt this is because you saving a values of 01/01/0001 to a field which which is DATETIME (which only accepts dates between 01/01/1753 to 12/31/9999) and not DATETIME2.
The reason the values of you dates are 01/01/0001 (which is the default for DateTime) is because you do not pass a model to the view so default values are used. The code in your GET needs to be
public ActionResult Create()
{
ViewBag.CITY_ID = new SelectList(db.LTCITies, "CITY_ID", "CITY_NAME", 1);
var entry = new Models.TRRESPONDENT
{
ENTRY_DATE = DateTime.Now,
AUDIT_TIME = DateTime.Now,
};
return View(entry); // return your model
}
However you should not use your data model in the view, and instead create a view model containing only the properties you need. Values such as ENTRY_DATE should only be set immediately before you save the data model to the database. For information on a creating a view model, refer What is ViewModel in MVC?.
The basic steps for creating a view model are
Create a new folder (say) ViewModels and copy you data model to and
and rename it (say)RespondentVM
Delete all the [Display] attributes from you data model (they are
view specific attributes)
Delete all the properties which the user will not be editing in the
view (e.g ENTRY_DATE and AUDIT_TIME) except the property which
is the objects ID which should be renamed to ID so its
automatically bound assuming your using the default routes (note its
not clear if you even have an ID property - I assume its
RESPONDENT_ID, but that should be an auto-incremented int in the
database -i.e. [Key]public int RespondentId { get; set; }). I also
recommend you rename all your properties to follow naming
conventions - EntryDate, not ENTRY_DATE.
Change all value types to be nullable and add the [Required]
attribute to protect against under-posting attacks (e.g. public int
CITY_ID { get; set; } becomes public int? CityID { get; set; }
Add additional properties for SelectList's etc that you are
currently assigning to ViewBag properties, e.g. public
IEnumerable<SelectListItem> CityList { get; set; }
You controller methods will then be
public ActionResult Create()
{
RespondentVM model = new RespondentVM();
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(RespondentVM model) // note a [Bind]` attribute is not required
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
// Initialize an instance of your data model and set its properties based on the view model
TRRESPONDENT respondent = new TRRESPONDENT()
{
FULL_NAME = model.FullName,
CITY_ID = model.CityID,
....
// Set default values
ENTRY_DATE = DateTime.Now,
....
}
db.TRRESPONDENTs.Add(respondent);
db.SaveChanges();
return RedirectToAction("Index");
}
// Common code for populating SelectLists etc - DRY!
private void ConfigureviewModel(RespondentVM model)
{
// Note - delete the 4th parameter of the SelectList constructor
model.CityID = new SelectList(db.LTCITies, "CITY_ID", "CITY_NAME");
}
And a few extra notes on your view code.
You do not need a hidden input for the ID property if its named ID
and your using the default routing
Since you have [Display(Name = "..")] attributes, then in the view
its just #Html.LabelFor(m => m.PropertyName), not
#Html.LabelFor(m => m.PropertyName, "some text")
To generate your dropdownlists, use #Html.DropDownListFor(m =>
m.CityID, Model.CityList, "Please select", new { ... }); - you
current implementation will not give correct 2-way model binding or
client side validation.
I’m trying to create a team of players, there are 4 players per team so I have 4 select lists that contain and populate the players in the league. When I go to save the team the error:
"There is no ViewData item of type 'IEnumerable' that has the key 'Skip'`
The CreateTeam controller:
public ActionResult CreateLeagueTeam(int? id)
{
int leagueId = id.Value;
League league = db.Leagues.Include(x=>x.Members).First(l=> l.Id == leagueId);
var leagueMemberList = league.Members.ToList();
var leagueMemberSelectListItems = new List<SelectListItem>();
foreach(Member m in leagueMemberList)
{
leagueMemberSelectListItems.Add(new SelectListItem() { Text = m.FirstName + " " + m.LastName, Value = m.Id.ToString() });
}
ViewData["leagueMemberList"] = leagueMemberSelectListItems;
return View();
}
the HTTP POST ActionResult:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateLeagueTeam([Bind(Include = "skip")] Team team)
{
team.IsBonspiel = false;
team.IsLeague = true;
// team.Name = team.Skip.LastName;
team.YearActive = games.getSeasonYear();
//finds and sets the league ID for the team
int leagueId = (int)Session["leagueId"];
League league = db.Leagues.Find(leagueId);
team.League = league;
if (ModelState.IsValid)
{
db.Teams.Add(team);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(team);
}
Finally the view where the Error is getting thrown:
<div class="form-group">
#Html.Label("Skip", null, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Skip, (IEnumerable<SelectListItem>)ViewBag.leagueMemberList, htmlAttributes: new { #class = "control-label col-md-2" })
</div>
</div>
Also the Team Model:
public class Team: Entity
{
[Required]
public bool IsBonspiel { get; set; }
[Required]
public bool IsLeague { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int YearActive { get; set; }
public int? SkipId { get; set; }
public Member Skip { get; set; }
public string BonspielSkip { get; set; }
public List<BonspielTeamMember> BonspielMembers { get; set; }
public List<Member> Members { get; set; }
public List<Game> Games { get; set; }
public Bonspiel Bonspiel { get; set; }
public League League { get; set; }
}
The are multiple errors with your code.
Skip is a complex object and you cannot bind a <select> to a
complex object. Based on your view, it should be
#Html.DropDownListFor(m => m.SkipId, ...)
You do not have a ViewBag property named leagueMemberList
(change the controller code to ViewBag.leagueMemberList =
leagueMemberSelectListItems; or the view code to
#Html.DropDownListFor(m => m.SkipId,
(IEnumerable<SelectListItem>)ViewData["leagueMemberList"], ...)
You do not reassign the value of ViewData["leagueMemberList"] (or
ViewBag.leagueMemberList) in the POST method if ModelState is
invalid and you return the view, which will result in a different
exception because it will be null (Refer this
question/answer
Your [Bind(Include = "skip")] code in the POST method means that
ModelState will always be invalid because you exclude every
property of the model from binding (except Skip and you dont post
any values for Skip)
You added data to "ViewData" but you try to access from ViewBag.
You should know ViewData is different with ViewBag.
Therefore you try to change this line:
ViewData["leagueMemberList"] = leagueMemberSelectListItems;
to => ViewBag.leagueMemberList = leagueMemberSelectListItems;
I'm picking up that it's a best practice to use the strongly-typed textboxfor helper method rather than simple textbox. I'm all for that. But as I made the switch in my project, the data stopped getting written back to the database. I'm having trouble figuring out why.
Here's my model.
public class MasterModel
{
[Key]
public int mandatoryKey { get; set; }
public List<tblAddress> Address { get; set; }
public List<tblPrimaryCaregiverdata> Primary { get; set; }
public List<tblPhone> Phone { get; set; }
public List<tblEmail> Email { get; set; }
public List<tblRelatedCaregiver> Related { get; set; }
public List<tblTrainingHistoryMain> TrainingHistory { get; set; }
public List<tblInquiryReferralStatu> InquiryReferral { get; set; }
}
Then the controller
public ActionResult Create(MasterModel masterModel)
{
if (ModelState.IsValid)
{
db.tblPrimaryCaregiverdatas.Add(masterModel.Primary[0]);
db.SaveChanges();
int newCareGiverID = db.tblPrimaryCaregiverdatas.OrderByDescending(p => p.CareGiverID)
.FirstOrDefault().CareGiverID;
foreach (var ph in masterModel.Phone)
{
ph.CareGiverID = newCareGiverID;
db.tblPhones.Add(ph);
}
db.SaveChanges();
return RedirectToAction("Index");
}
Now, in the view (which invokes several partial views, one for each table in the master model), when I created the fields like this:
SelectList phonetypes = ViewBag.PhoneType;
<div>
<label class="label-fixed-width">Phone:</label>
#Html.TextBox("masterModel.Phone[0].phone", null, new { style = "width: 600px" })
#Html.DropDownList("masterModel.Phone[0].PhoneType",phonetypes, null, new
{
#class = "form-control-inline dropdown",
style = "width: 100px"
})
...I was able to write data back into the database. But when I switched over to textboxfor like this:
SelectList phonetypes = ViewBag.PhoneType;
<div>
<label class="label-fixed-width">Phone:</label>
#Html.TextBoxFor(x => x.Phone[0].Phone, null, new { style = "width: 600px" })
#Html.DropDownListFor(x => x.Phone[0].PhoneType, phonetypes,"--------", new
{
#class = "form-control-inline dropdown",
style = "width: 100px"
})
The Phone section of the MasterModel is empty when I post back. Can someone help me understand what's going on here?
When you post a model back to an ActionResult and return the same View, the values for the model objects are contained in the ModelState. The ModelState is what contains information about valid/invalid fields as well as the actual POSTed values. If you want to update a model value, you can do this:
foreach (var ph in masterModel.Phone)
{
ModelState.Clear()//added here
ph.CareGiverID = newCareGiverID;
db.tblPhones.Add(ph);
}
I want to get dropdown list with values from table. I'm have model:
namespace MobileService.Models
{
public class Mobile
{
public int Id { get; set; }
public string Model { get; set;}
Public string EMEI { get; set ;}
public int MasterId { get; set; }
public List<Master> MasterList { get; set; }
}
public class Master
{
public int Id { get; set; }
public string Name { get; set; }
}
}
In controller I creat action for this model:
public ActionResult Create()
{
return View();
}
In view:
#model MobileService.Models.Mobile
#using (Html.BeginForm()) {
#Html.EditorFor(model => model.Model)
#Html.EditorFor(model => model.EMEI )
// And here i want to display a dropdown list with all available masters
<button type="submit" class="btn btn-primary">Creat</button>
}
But it always tell me that Model.MasterList is null . But why? In model i told to get list from another model (public List MasterList { get; set; }). Why is it null?
This code is in VB. In the beginning even i looked for a lot of time this is the simple solution i found.
Convert the model into list of selectListItems
Dim lstEmpTypes As New List(Of SelectListItem)
lstTicketWrTypes.Add(New SelectListItem With {.Text = row("Something"), .Value = row("Something")})
'Then load it into a ViewBag
ViewBag.EmpTypes = lstEmpTypes
'And in you View
#Html.DropDownList("selectWrType", New SelectList(ViewBag.EmpTypes , "Value", "Text"), New With {.class = "span3"})
When you query for Mobile you need to Include("MasterList"), or turn lazy loading on on your context (not recommended)
The answer for me was to add this to controller:
public ActionResult Create()
{
ViewBag.MasterId = new SelectList(db.Masters, "Id", "Name");
return View();
}
Then in view to show droplist:
#Html.DropDownList("MasterId", null, htmlAttributes: new { #class = "form-control" })
Thnx ZikO who let me now that list didn't loaded automatical.