moka
moka

Reputation: 35

ASP.NET MVC 5 - Dropdownlist from another model

Good day ! I am very new to ASP.NET and tried to research multiple tutorials and would much appreciate this community's feedback.

I am trying to build a cascading dropdownlist from another model. In the course I created a CombinedModel

Model-view

//Combined model
namespace WebApplication2.Models
{
public class CombinedModel
{
    public RegisterViewModel RegisterViewModel { get; set; }
    public DistrictModel Districtmodel { get; set; }
}
}


    //Model 1
    public class RegisterViewModel
    {
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    public string ConfirmPassword { get; set; }

    public virtual List<DistrictModel> DistrictName { get; set; }

 //Model 2
 namespace WebApplication2.Models
 {
public class DistrictModel
 {
    public int DistrictID { get; set; }
    public string DistrictName { get; set; }
 }
 }

Controller-View

    public ActionResult Register()
    {
        ViewBag.DistrictNameList = new SelectList(db.DistrictModel,               "DistrictName", "DistrictName");
        return View();
    }

View

     model WebApplication2.Models.CombinedModel
     using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
       <div class="col-md-10">

     Html.DropDownListFor(m => m.RegisterViewModel.DistrictName, ViewBag.DistrictNameList, new { @class = "form-control" } )
    </div>

And it doesn't seem to work... I tried changing it to Enum and its still wouldn't comply. I would appreciate your feedback on this !

Upvotes: 0

Views: 3752

Answers (4)

Victor.Uduak
Victor.Uduak

Reputation: 2824

Ok

the District Model

 public class DistrictModel
 {
    public int Id { get; set; }
    public string DistrictName { get; set; }
 }

the RegisterViewModel

public class RegisterViewModel
{
  [DataType(DataType.Password)]
  [Display(Name = "Confirm password")]
  public string ConfirmPassword { get; set; }

  //Mapping 
  public int DistrictId { get; set; }
  public virtual List<DistrictModel> District { get; set; }
}

At the Controller Level

 public ActionResult Register()
 {
    List<DistrictModel> districtModelList = db.DistrictModel.ToList();
    ViewData["DistrictNameList"] = districtModelList.Select(x => new SelectListItem { Value = x.Id , Text = x.DistrictName  });
    return View();
 }  

At the View

model RegisterViewModel
@using (Html.BeginForm("Index", "home", FormMethod.Post,
                                  new { @class = "form-horizontal", role = "form" }))
{
  @Html.DropDownListFor(model => model.DistrictId, (IEnumerable<SelectListItem>)ViewData["DistrictNameList"], "[Select District]", new { @class = "form-control" })
  <input type="submit" />
}

Upvotes: 0

moka
moka

Reputation: 35

thanks for all the replies, I thought to post the final workaround and share it with all. The issue was that I did not setup the models properly. I also had to add view bag in Get/Post and changed to dropdownlistfor in view.

Model

 public class AssetRequest
    {
        public int Id { get; set; }

        [DataType(DataType.Date)]
        [Display(Name = "Request date")]
        public DateTime AssetRequestDate { get; set; }



        [Display(Name = "Facility")]
        public int FacilityId { get; set; }
        public virtual Facility Facility { get; set; }

 public class Facility
    {
        public int Id { get; set; }


        [Display(Name="Asset")]
        public string AssetName { get; set; }

        public virtual ICollection<AssetRequest> AssetRequests { get; set; }
    }

public DbSet<AssetRequest> AssetRequestTable { get; set; }
        public DbSet<Asset> AssetTable { get; set; }

        public DbSet<District> DistrictTable { get; set; }

Controller

 // GET: AssetRequests/Create
        public ActionResult Create()
        {

            ViewBag.RequestStatusId = "New request";
            ViewBag.AssetRequestDate = DateTime.Now;
            ViewBag.AssetId = new SelectList(db.AssetTable, "Id", "AssetName");
            ViewBag.DistrictId = new SelectList(db.FacilitytTable, "Id", "DistrictName");
            ViewBag.RequestTypeId = new SelectList(db.RequestTypeTable, "Id", "RequestTypeName");
            return View();
        }


[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Create([Bind(Include = "Id,AssetRequestDate,FacilityId,AssetId,RequestTypeId, RequestStatusId")] AssetRequest assetRequest)
        {
            var currentUser = await manager.FindByIdAsync(User.Identity.GetUserId());

            if (ModelState.IsValid)
            {
                assetRequest.User = currentUser;
                assetRequest.AssetRequestDate = DateTime.Now;
                assetRequest.RequestStatusId = 1;
                db.AssetRequestTable.Add(assetRequest);
                await db.SaveChangesAsync();
                return RedirectToAction("Index");
            }

Thanks for all the replies !

Upvotes: 0

Curiousdev
Curiousdev

Reputation: 5788

Change this line

public virtual List<DistrictModel> DistrictName { get; set; }

To this

public virtual string DistrictName { get; set; }

OR

Change your code as below

Model

public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "Email")]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        public string ConfirmPassword { get; set; }

        public virtual string DistrictName { get; set; }

        public virtual SelectList DistrictList { get; set; }

    }
    public class DistrictModel
    {
        public int DistrictID { get; set; }
        public string DistrictName { get; set; }
    }

    public class CombinedModel
    {
        public RegisterViewModel RegisterViewModel { get; set; }
        public DistrictModel Districtmodel { get; set; }
    }

Controller

        CombinedModel obj = new CombinedModel();
        obj.RegisterViewModel = new RegisterViewModel();;
        obj.RegisterViewModel.DistrictList = new SelectList(db.DistrictModel, "DistrictName", "DistrictName");;
        return View(obj);

View

@using (Html.BeginForm("Index", "home", FormMethod.Post,
                                      new { @class = "form-horizontal", role = "form" }))
{
    @Html.DropDownListFor(model => model.RegisterViewModel.DistrictName, Model.RegisterViewModel.DistrictList, new { @class = "form-control" })
    <input type="submit" />
}

Upvotes: 1

Shyju
Shyju

Reputation: 218732

Your question does not have any code about any cascading dropdowns! But i see a problem with your code to render the dropdown.

You need to cast the viewBag items to a SelectList beause the DropDownListFor overload expects that, not a dynamic object!

@using (Html.BeginForm("Index", "home", FormMethod.Post,
                                      new { @class = "form-horizontal", role = "form" }))
{
    @Html.DropDownListFor(m => m.RegisterViewModel.DistrictName, 
                 ViewBag.DistrictNameList as SelectList, new { @class = "form-control" })
    <input type="submit" />
}

Upvotes: 0

Related Questions