MVC drop down list - null error - model-view-controller

I have generated Models classes using Entity Framework.
This is what I got:
public partial class Employees
{
public Employees()
{
this.Employees1 = new HashSet<Employees>();
this.Vacations = new HashSet<Vacations>();
}
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string Phone { get; set; }
public string JobTitle { get; set; }
public int ManagerID { get; set; }
public string LastUpdatedBy { get; set; }
public Nullable<System.DateTime> LastUpdatedDate { get; set; }
public bool Status { get; set; }
public virtual ICollection<Employees> Employees1 { get; set; }
public virtual Employees Manager { get; set; }
public virtual ICollection<Vacations> Vacations { get; set; }
}
Then I've created View Model for that class:
public class EmployeeViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string Phone { get; set; }
public string JobTitle { get; set; }
public int ManagerID { get; set; }
public string ManagerFullName
{
get
{
return FirstName + " " + LastName;
}
}
public bool Status { get; set; }
public virtual ICollection<Employees> Employees1 { get; set; }
public virtual Employees Manager { get; set; }
}
In EmplyeeControler class I have action:
public ActionResult Create()
{
EmployeeViewModel employeeVM = new EmployeeViewModel();
ViewBag.Employees1 = new SelectList(employeeVM.Employees1, "EmployeeID", "ManagerFullName");
return View(employeeVM);
}
And view:
<div class="editor-label">
#Html.LabelFor(model => model.ManagerID, "Manager")
</div>
<div class="editor-field">
#Html.DropDownList("ManagerID", "--- Select Manager ---")
#Html.ValidationMessageFor(model => model.ManagerFullName)
</div>
But I am receiving error on line:
Value cannot be null. Parameter name: items
ViewBag.Employees1 = new SelectList(employeeVM.Employees1, "EmployeeID", "ManagerFullName");
What is wrong in my code?

<div class="editor-label">
#Html.LabelFor(model => model.ManagerID, "Manager")
</div>
<div class="editor-field">
#Html.DropDownListFor(x => x.ManagerID, (IEnumerable<SelectListItem>)ViewBag.Employees1,"--- Select Manager ---"));
#Html.ValidationMessageFor(model => model.ManagerFullName)
</div>
More Details See this link

Related

Dropdownlist in MVC Error

i created a dropdown list in MVC page,i want when changed id,new data pass to Action with below code:
#if (ViewBag.IdType==1)
{
#Html.DropDownListFor(m => m.Citycode, new SelectList(ViewBag.ResultList as System.Collections.IEnumerable, "Citycode", "CityName","1"))
#Html.ValidationMessageFor(model => model.Citycode)
}
else
{
#Html.DropDownListFor(m => m.IDReshteh, new SelectList(ViewBag.ResultList as System.Collections.IEnumerable, "IDReshteh", "ReshteName",Model.IDReshteh),"Fselect")
#Html.ValidationMessageFor(model => model.IDReshteh)
}
<input type="hidden" id="SelValue" value="1"/>
<input type="submit" value="Submit" />
</p>
/*<input type="hidden" name="HDcity" id="HDcity" />*/
<div id="LoadData">
#Html.Action("selVahedListAjax", new { IdReshte = ViewBag.ChooseItem, IdCity = Model.IDReshteh })
</div>
Model:
public class TInfo
{
[Key]
public int Id { get; set; }
[Required]
public string Scode { get; set; }
[Required]
public string SName { get; set; }
[Required]
public string TName { get; set; }
public string ModirName { get; set; }
public string FZamineh { get; set; }
public string TAddress { get; set; }
public string PcodeSh { get; set; }
public string TelcodeSh { get; set; }
public string FaxcodeSh { get; set; }
public string DAddress { get; set; }
public string PcodeDa { get; set; }
public string TelcodeDa { get; set; }
public string FaxcodeDa { get; set; }
public string WebsiteAddress { get; set; }
public string EmailAdd { get; set; }
public string TablighatPic { get; set; }
[Required]
public int Citycode { get; set; }
[ForeignKey ("Citycode")]
public Lcity City { get; set; }
[Required]
public int IDReshteh { get; set; }
[ForeignKey("IDReshteh")]
public RFaaliat Reshteh { get; set; }
}
My controller:
//If IdType=1 then user clicked on Reshteh But if IdType=2 then user clicked on city
public ActionResult selVahedList(int IdType, int IdChoose)
{
ViewBag.ChooseItem = IdChoose;
ViewBag.IdType = IdType;
if (IdType == 1)
ViewBag.ResultList = Dbcon.Lcitys.ToList();
else
ViewBag.ResultList = Dbcon.RFaaliats.ToList();
return View();
}
public ActionResult selVahedListAjax(int IdReshte,int IdCity )
{
ViewBag.Reshteh = IdReshte;
var res = Dbcon.TaavoniInfos.Where(m => m.IDReshteh == IdReshte && m.Citycode ==?);//Idont know what should put here
return PartialView(res);
}
my problem is i cant get and pass selected item in drop down and update data in page. please help me.
thanks a lot

MVC 3 EF retrieve Many to One from model

I'm creating a page that will display 6 blogs that were created in the passed 7 days. The blog contains an image and multiple comments
Here is the Blog model
public class Blog
{
public int BlogID { get; set; }
public int likes { get; set; }
public int ImageID { get; set; }
public Boolean removed { get; set; }
public DateTime dte_created { get; set; }
public DateTime? dte_modified { get; set; }
public virtual Image Image { get; set; }
public virtual ICollection<Comment> Comment { get; set; }
}
And here's the blogContent.
public class Image
{
public int ImageID { get; set; }
public string img_path { get; set; }
public string Description { get; set; }
public DateTime dte_created { get; set; }
}
public class Comment
{
public int CommentID { get; set; }
public string Commentation { get; set; }
public int likes { get; set; }
public int BlogID { get; set; }
public DateTime dte_created { get; set; }
public DateTime? dte_modified { get; set; }
public Boolean removed { get; set; }
//public virtual int Account_ID { get; set; }
public virtual Blog Blog { get; set; }
}
Here is the controller
private ACaptureDB db = new ACaptureDB();
public ViewResult Index()
{
ViewBag.Message = "ArchiCapture";
var dateCheck = DateTime.Now.AddDays(-7);
var results = from r in db.Blog
where r.dte_created >= dateCheck
select r;
return View(results);
}
and my View.
#model IEnumerable<ACapture.Models.Blog>
#{
ViewBag.Title = "Home Page";
}
<div class="Forum">
<p>The Forum</p>
<form class="Forum" runat="server">
#foreach (var item in Model)
{
<div class="ForumChild"><img src="#item.Image.img_path" alt="Not Found" />
<br />
<table>
?????????
</table>
</div>
}
</form>
</div>
How would I retrieve all the comments that are linked to the blog?
You should be able to loop over the Comments collection in your model blog object:
<table>
#foreach(var comment in Model.Comments) {
<tr>
<td>#comment.Commentation</td>
....
</tr>
}
</table>

Trouble with Model.IsValid on a property thats not required

I am having trouble with Model.IsValid on a property that's not required.
Here's the code.
BeginForm in the Edit.cshtml file
#using (Html.BeginForm("Edit", "Member", FormMethod.Post, new { enctype = "multipart/formdata" }))
{
#Html.Partial("_MemberForm", Model.Member)
}
MemberEditViewModel: (used for the Edit.cshtml file)
public class MemberEditViewModel
{
public MemberFormModel Member { get; set; }
}
MemberFormModel:
public class MemberFormModel : ICreateMemberCommand, IValidatableObject
{
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string SocialSecurityNumber { get; set; }
[Required]
public int PinCode { get; set; }
[Required]
public char Gender { get; set; }
public string Email { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string ZipCode { get; set; }
[Required]
public string ZipAddress { get; set; }
public string Phone { get; set; }
public string Phone2 { get; set; }
[Required]
public string City { get; set; }
[Required]
public int CountryId { get; set; }
//not required (but still displaying error it's required)
public Membership Membership { get; set; }
// not required (displaying error it's required)
public PunchCard PunchCard { get; set; }
public bool IsActive { get; set; }
block of _MemberForm.cshtml (partial)
<fieldset>
<dl>
<dt>#Html.LabelFor(m => m.Id)</dt>
<dd>#Html.TextBoxFor(m => m.Id, new { disabled = "disabled", #readonly = "readonly" })</dd>
<dt>#Html.LabelFor(m => m.PinCode)</dt>
<dd>#Html.EditorFor(m => m.PinCode)</dd>
<!-- problem with membership, maybe with the .FromData/ToDate ? -->
<dt>#Html.LabelFor(m => m.Membership)</dt>
<dd>#Html.EditorFor(m => m.Membership.FromDate, new { #name = "Membership" }) -
#Html.EditorFor(m => m.Membership.ToDate, new { #name="Membership"})</dd>
<!-- problem with punch card, maybe with the .Times ? -->
<dt>#Html.LabelFor(m => m.PunchCard)</dt>
<dd>#Html.EditorFor(m => m.PunchCard.Times, new { #name = "PunchCard" })</dd>
</dl>
</fieldset>
The MemberController Edit Action
// POST: /Members/10002/Edit
[HttpPost]
public ActionResult Edit(FormCollection formValues, MemberFormModel memberForm)
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
if(IsSaveOperation(formValues)){
if(TryUpdateMember(memberForm)){
return RedirectToAction("Details", "Member", new {id = memberForm.Id});
}
}
var mm = new MemberEditViewModel{ Member = memberForm };
return View(mm);
}
Membership.cs
public class Membership
{
public Membership(){ /* empty constructor */}
public Membership(int id, int memberId, DateTime fromDate, DateTime toDate)
{
Id = id;
MemberId = memberId;
FromDate = fromDate;
ToDate = toDate;
}
public int Id { get; set; }
public int MemberId { get; set; }
[DataType(DataType.Date)]
public DateTime FromDate { get; set; }
[DataType(DataType.Date)]
public DateTime ToDate { get; set; }
}
PunchCard.cs
public class PunchCard
{
public PunchCard() { /* empty constructor */ }
public PunchCard(int memberId, int times, DateTime createdDate, DateTime modifiedDate)
{
this.MemberId = memberId;
this.Times = times;
this.CreatedDate = createdDate;
this.ModifiedDate = modifiedDate;
}
public int Id { get; set; }
public int MemberId { get; set; }
public int Times { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}
You see I dont have any [Required] attribute, neither in the MemberFormModel. So how come those two are Required ? Its a mystery.
You should not be using both the disabled and readonly attribute on your textbox:
#Html.TextBoxFor(m => m.Id, new { disabled = "disabled", #readonly = "readonly" })
I guess the disabled attribute takes precedence and the value of the Id is never sent to the server when you submit the form. That's why you get a modelstate error. Because your id property is required. Now you will be probably tell me that it is not decorated with the [Required] attribute but this doesn't matter. Since you have declared it as a non-nullable integer it is implicitly required and the framework automatically makes it required. If you don't want this to happen you should declare it as a nullable integer.
So back to your view, if you want to only display id, without allowing the user to modify it, use readonly:
#Html.TextBoxFor(m => m.Id, new { #readonly = "readonly" })
Obviously don't think that if you made a textbox readonly, the user cannot modify it. The normal user will not. But a hacker could always put whatever value he wants in this textbox and forge a request. So absolutely do not rely on this as some sort of security or something.

MVC 3 Dropdowns & Multiple Model ViewModel

I'm pretty new to MVC, but I'm trying to set up a two step user registration system. I have an register model and several other models in a viewmodel called Registration. A user will have a profile based on the register model and then they will select a Producer/Distributor/Restaurant/Importer that they are part of, or create a new one of those. My ViewModel that is returned doesn't validate or pickup the values in my dropdownlists. They populate correctly, but on the post they aren't in the vm. Below is my view/controller/and models. I've been searching the net for 2 days with no luck. Also, if you think my method of registration is wacky, let me know. Thanks!
controller:
public class RegistrationController : Controller
{
private vfContext db = new vfContext();
//
// GET: /Registration/
public ActionResult Register()
{
ViewBag.UserTypeID = new SelectList(db.UserTypes, "UserTypeID", "Name");
ViewBag.ProducerID = new SelectList(db.Producers, "ProducerID", "Name");
ViewBag.PublicationID = new SelectList(db.Publications, "PublicationID", "Name");
ViewBag.ImporterID = new SelectList(db.Importers, "ImporterID", "Name");
ViewBag.DistributorID = new SelectList(db.Distributors, "DistributorID", "Name");
ViewBag.RestaurantID = new SelectList(db.Restaurants, "RestaurantID", "Name");
RegistrationViewModel reg = new RegistrationViewModel();
ViewData.Model = reg;
return View("Registration");
}
[HttpPost]
public ActionResult Register(RegistrationViewModel vm)
{
if (ModelState.IsValid)
{
MembershipCreateStatus createStatus;
//email is userid
Membership.CreateUser(vm.Register.Email, vm.Register.Password, vm.Register.Email, null, null, true, null, out createStatus);
if (createStatus == MembershipCreateStatus.Success)
{
Profile current = Profile.GetProfile(vm.Register.Email);
current.FirstName = vm.Register.FirstName;
current.LastName = vm.Register.LastName;
current.Address1 = vm.Register.Address1;
current.Address2 = vm.Register.Address2;
current.City = vm.Register.City;
current.State = vm.Register.State;
current.Postal = vm.Register.Postal;
current.UserTypeID = vm.Register.UserTypeID;
view - i'm having a hard time copying it over, so the issue is with ddls, so here is how I have the user type id one done
#model vf2.Models.RegistrationViewModel
<div class="editor-label">
#Html.LabelFor(model => model.Register.UserTypeID, "User Type")
</div>
<div class="editor-field">
#Html.DropDownList("UserTypeID", String.Empty)
#Html.ValidationMessageFor(m => m.Register.UserTypeID)
</div>
Models:
public class RegistrationViewModel
{
public RegisterModel Register { get; set; }
public Producer Producer { get; set; }
public Distributor Distributor { get; set; }
//public Publication Publication { get; set; }
public Restaurant Restaurant { get; set; }
public Importer Importer { get; set; }
}
Here is my register model.
public class RegisterModel
{
//[Required]
//[Display(Name = "User name")]
//public string UserName { get; set; }
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "Address")]
public string Address1 { get; set; }
[Display(Name = "Address Cont.")]
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postal { get; set; }
public string Country { get; set; }
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }
public int ProducerID { get; set; }
public int DistributorID { get; set; }
public int PublicationID { get; set; }
public int ImporterID { get; set; }
public int RestaurantID { get; set; }
public virtual Producer Producer{ get; set; }
public virtual Distributor Distributor { get; set; }
public virtual Publication Publication { get; set; }
public virtual Importer Importer { get; set; }
public virtual Restaurant Restaurant { get; set; }
[Required]
public int UserTypeID { get; set; }
public virtual UserType UserType { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
producer model:
public class Producer
{
public int ProducerID { get; set; }
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postal { get; set; }
public string Country { get; set; }
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public string Website { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public string UpdatedBy { get; set; }
public DateTime? UpdatedOn { get; set; }
public Boolean Active { get; set; }
public virtual ICollection<Wine> Wines { get; set; }
}
I think I figured this out by adding a the following to my viewmodel:
public IEnumerable<UserType> UserTypes { get; set; }
public IEnumerable<Producer> Producers { get; set; }
and then this to my view:
#Html.DropDownListFor(m=>m.Register.UserTypeID,new SelectList(Model.UserTypes,"UserTypeID","Name"),"Select account type")

When using ASP.NET MVC 3 with EF 4.1 Code First, I can only edit the main table, what am I doing wrong?

A brief description of what I am doing. I am creating a rather crude IS Asset tracking database using ASP MVC 3 and EF Code First approach. I can create a new asset. I can view the details on an asset. I can even display the edit view and edit the AssetTag. However the record will not update any of the other fields. If I edit the LocationName for instance. It will act like it is posting and return me to the Index view, but the record never actually posts the change.
I have created the Model below
public class AssetModel
{
public int id { get; set; }
public string AssetTag { get; set; }
public virtual Location Location { get; set; }
public virtual Hardware Hardware { get; set; }
public virtual Software Software { get; set; }
public virtual User User { get; set; }
}
public class Location
{
public int LocationId { get; set; }
public string LocationName { get; set; }
}
public class Hardware
{
public int HardwareId { get; set; }
public string Manufacturer { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
public class Software
{
public int SoftwareId { get; set; }
public string PublisherName { get; set; }
public string SoftwarePackageName { get; set; }
public string SoftwarePackageVersion { get; set; }
public string SerialNumber { get; set; }
public bool IsVolumeLicense { get; set; } // as in "Yes this is a Vol. Lic. Agreement"
public LicenseAgreement LicenseAgreement { get; set; }
}
public class LicenseAgreement
{
public int LicId { get; set; }
public string VolumeLicenseAgreementCompany { get; set; }
public string AgreementIdentifier { get; set; }
public DateTime VolumeLicenseStartDate { get; set; }
public DateTime VolumeLicenseExpirationDate { get; set; }
public Int16 NumberOfLicenses { get; set; }
}
public class User
{
// may remove this at some time and pull from Active Directory.
// for now we take the easy route.
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
I have this DbDataSet that uses the AssetModel above:
public class AssetContext : DbContext
{
public DbSet<AssetModel> Assets { get; set; }
}
In my AssetController I have this for Edit:
public ActionResult Edit(int id)
{
AssetModel assetmodel = db.Assets.Find(id);
return View(assetmodel);
}
//
// POST: /Asset/Edit/5
[HttpPost]
public ActionResult Edit(AssetModel assetmodel)
{
if (ModelState.IsValid)
{
db.Entry(assetmodel).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(assetmodel);
}
And here is the Edit.cshtml
#model ISHelpDesk.Models.AssetModel
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm("Edit", "Asset")) {
#Html.ValidationSummary(true)
<fieldset>
<legend>AssetModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.AssetTag)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AssetTag)
#Html.ValidationMessageFor(model => model.AssetTag)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Location.LocationName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Location.LocationName)
#Html.ValidationMessageFor(model => model.Location.LocationName)
</div>
</fieldset>
<p><input type="submit" value="Save"</p>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
your AssetContext should be
public class AssetContext : DbContext
{
public DbSet<AssetModel> Assets { get; set; }
public DbSet<Location> Locations { get; set; }
public DbSet<Hardware> Hardwares { get; set; }
public DbSet<Software> Softwares { get; set; }
public DbSet<LicenseAgreement> LicenseAgreements { get; set; }
public DbSet<User> Users { get; set; }
}
this is registering each of your classes as a table in the DbContext, what you had before showed your DbContext consists only of AssetModel
Update: The issue may be that when you get to the post method of the edit, the Asset is no longer associated with the database Asset it was originally loaded from, have a go at changing it to
public ActionResult Edit(int id)
{
AssetModel assetmodel = db.Assets.Find(id);
return View(assetmodel);
}
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
AssetModel assetmodel = db.Assets.Find(id);
if (TryUpdateModel(assetmodel))
{
db.SaveChanges();
return RedirectToAction("Index");
}
return View(assetmodel);
}
Obviously this may not be the behaviour you want I'm just trying to see if you can get some changes persisted and go from there
Your Model classes should extend DbContext:
public class AssetModel :DbContext{}

Resources