Dropdownlistfor how to use?

Asked

Viewed 720 times

3

I’m having a question on how popular and then pick up the selected item from a DropDownListFor, I am using DDD architecture and Entity Framework.

In case here my class ServiceProviderViewModel has to have relationship with other classes. I would like to know how to do to popular this Helper in View of Create.

Follows codes:

public class ServiceProviderViewModel
{
    [Key]
    public int ServiceProviderId { get; set; }

    [Required(ErrorMessage = "Por favor, informe o nome do colaborador.")]
    [Display(Name = "Nome:")]
    public string Name { get; set; }

    [Display(Name = "Nome da Mãe:")]
    public string MotherName { get; set; }

    [Display(Name = "Nome do Pai:")]
    public string FatherName { get; set; }

    [Display(Name = "E-mail:")]
    [EmailAddress(ErrorMessage = "Por favor, informe um formato de e-mail válido.")]
    public string Email { get; set; }

    [Display(Name = "Nascimento:")]
    public DateTime Birth { get; set; }

    [ScaffoldColumn(false)]
    public DateTime DateRegister { get; set; }

    [ScaffoldColumn(false)]
    public DateTime DateModified { get; set; }

    [Required(ErrorMessage = "Por favor, informe o departamento para o colocaborador.")]
    [Display(Name = "Departamento:")]       
    public int DepartamentId { get; set; }

    [Required(ErrorMessage = "Por favor, informe o departamento para o colocaborador.")]
    [Display(Name = "Cargo/Função:")]
    public int PositionId { get; set; }

    public virtual DepartamentViewModel Departaments { get; set; }
    public virtual PositionViewModel Positions { get; set; }

    public virtual IEnumerable<ServiceProviderAddressViewModel> ServiceProviderAddress { get; set; }
    public virtual IEnumerable<ServiceProviderPhoneViewModel> ServiceProviderPhone { get; set; }
    public virtual IEnumerable<ServiceProviderInfoViewModel> ServiceProviderInfo { get; set; }
    public virtual IEnumerable<InfoBankViewModel> InfoBank { get; set; }
}

In the Controller:

 public class ServiceProviderController : Controller
{
    private readonly IServiceProviderAppService _serviceProviderApp;

    public ServiceProviderController(IServiceProviderAppService serviceProviderApp)
    {
        _serviceProviderApp = serviceProviderApp;
    }

    // GET: ServiceProvider
    public ActionResult Index()
    {
        var serviceProviderViewModel = Mapper.Map<IEnumerable<ServiceProvider>, IEnumerable<ServiceProviderViewModel>>(_serviceProviderApp.GetAll());
        return View(serviceProviderViewModel);
    }

    // GET: ServiceProvider/Create
    public ActionResult Create()
    {
        return View();
    }

    // POST: ServiceProvider/Create
    [HttpPost]
    public ActionResult Create(ServiceProviderViewModel serviceProvider)
    {
        if (ModelState.IsValid)
        {
            var serviceProviderDomain = Mapper.Map<ServiceProviderViewModel, ServiceProvider>(serviceProvider);
            _serviceProviderApp.Add(serviceProviderDomain);
            _serviceProviderApp.Save();

            return RedirectToAction("Index");
        }

        return View(serviceProvider);
    }

...

For each class that ServiceProvider relates have the models specific to the realization of CRUD. I just don’t know how I should do to run this mixture of models among the views and controllers.

3 answers

3

Code taking into account that the Positionid should be a combo:

Na Action Get:

Obs: You must pass the Viewbag.Position

public ActionResult Create()
{
    ViewBag.Position = new SelectList(_serviceProviderApp.SeuMetodoDeObterPositions(), "PositionId", "SeuCampoDescricao");

    return View();
}

In view:

Obs: This Code puts the first option blank and then the data coming from Viewbag.

@Html.DropDownList("PositionId", (IEnumerable<SelectListItem>)ViewBag.Position, String.Empty, new { @class = "form-control" })
  • But since the Position class is another model, should I make a call from it inside the Serviceprovider controller? The idea isn’t exactly to create separate controllers for each model?

  • @Uitanmaciel, I spoke Position only as illustration. Instead of Position put the model referring to your combo.

  • It’s working fine. It’s populating the Dropdownlistfor. However you are giving error: An Exception of type 'System.Invalidoperationexception' occurred in System.Web.Mvc.dll but was not handled in user code Additional information: The Viewdata item that has the key 'Departamentid' is of type 'System.Int32' but must be of type 'Ienumerable<Selectlistitem>'. You’re having trouble converting the guy.

  • Maybe I need to see your code, but understand that the Obtain positions method (or whatever the name of your method needs to return something like Ienumerable<Position>, with the Position class having a Positionid property as key and a Description property that must be equal to the last two parameters passed to the New Selectlist.

  • look at the code below:

  • @Uitanmaciel, I looked at the code you posted and it seems ok to me. Complicated to know exactly what the problem is now. Probably you missed some detail, try debugging, see which line the problem occurs, see innerexception. Check the implementation of the Departament and repository class. It seems that the problem is to do the Get and not the Post, since in the post you do not use Viewbag.

Show 1 more comment

2


@uitan, this Exception is masking the real problem that should only be validation of your form. You must load the Viewbags from the post action as you did in the Get action. your post should look like this:

// POST: ServiceProvider/Create
[HttpPost]
public ActionResult Create(ServiceProviderViewModel serviceProvider)
{
    if (ModelState.IsValid)
    {
        var serviceProviderDomain = Mapper.Map<ServiceProviderViewModel, ServiceProvider>(serviceProvider);
        _serviceProviderApp.Add(serviceProviderDomain);
        _serviceProviderApp.Save();

        return RedirectToAction("Index");
    }

    //FALTAM ESSAS LINHAS:
    ViewBag.Position = new SelectList(_positionApp.GetAll(), "PositionId", "Description");
    ViewBag.Departament = new SelectList(_departamentApp.GetAll(), "DepartamentId", "Description");

    return View(serviceProvider);
}

Mark as solved if it works. :)

0

In the Domain:

 public class ServiceProvider
{
    #region Attributs
    public int ServiceProviderId { get; set; }
    public string Name { get; set; }
    public string MotherName { get; set; }
    public string FatherName { get; set; }        
    public string Email { get; set; }
    public DateTime Birth{ get; set; }
    public DateTime DateRegister { get; set; }
    public DateTime DateModified { get; set; }
    #endregion
    #region Foreingkeys
    public int DepartamentId { get; set; }
    public int PositionId { get; set; }
    #endregion
    #region Properties Navigations
    public virtual Departament Departaments { get; set; }
    public virtual Position Positions { get; set; }
    #endregion
}

public class Position
{
    #region Attributs
    public int PositionId { get; set; }
    public string Description { get; set; }
    public DateTime DateRegister { get; set; }
    public DateTime DateModified { get; set; }
    #endregion
    #region Relationships Other Class
    public virtual IEnumerable<ServiceProvider> ServiceProviders { get; set; }
    #endregion
}

 public class Departament
{
    #region Attributs
    public int DepartamentId { get; set; }
    public string Description { get; set; }
    public DateTime DateRegister { get; set; }
    public DateTime DateModified { get; set; }
    #endregion
    #region Relationships Other Class
    public virtual IEnumerable<ServiceProvider> ServiceProviders { get; set; }
    #endregion
}

In Viewmodel (Presentation Layer)

public class ServiceProviderController : Controller
{
    private readonly IServiceProviderAppService _serviceProviderApp;
    private readonly IPositionAppService _positionApp;
    private readonly IDepartamentAppService _departamentApp;

    public ServiceProviderController(IServiceProviderAppService serviceProviderApp, IPositionAppService positionApp, IDepartamentAppService departamentApp)
    {
        _serviceProviderApp = serviceProviderApp;
        _positionApp = positionApp;
        _departamentApp = departamentApp;
    }

    // GET: ServiceProvider
    public ActionResult Index()
    {
        var serviceProviderViewModel = Mapper.Map<IEnumerable<ServiceProvider>, IEnumerable<ServiceProviderViewModel>>(_serviceProviderApp.GetAll());
        return View(serviceProviderViewModel);
    }

    // GET: ServiceProvider/Details/5
    public ActionResult Details(int id)
    {
        return View();
    }

    // GET: ServiceProvider/Create
    public ActionResult Create()
    {
        ViewBag.Position = new SelectList(_positionApp.GetAll(), "PositionId", "Description");
        ViewBag.Departament = new SelectList(_departamentApp.GetAll(), "DepartamentId", "Description");
        return View();
    }

    // POST: ServiceProvider/Create
    [HttpPost]
    public ActionResult Create(ServiceProviderViewModel serviceProvider)
    {
        if (ModelState.IsValid)
        {
            var serviceProviderDomain = Mapper.Map<ServiceProviderViewModel, ServiceProvider>(serviceProvider);
            _serviceProviderApp.Add(serviceProviderDomain);
            _serviceProviderApp.Save();

            return RedirectToAction("Index");
        }

        return View(serviceProvider);
    }
}

Na View:

<div class="form-group">
            @Html.LabelFor(model => model.DepartamentId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.DepartamentId, (IEnumerable<SelectListItem>)ViewBag.Departament, string.Empty)
                @Html.ValidationMessageFor(model => model.DepartamentId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.PositionId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.PositionId, (IEnumerable<SelectListItem>)ViewBag.Position, string.Empty)
                @Html.ValidationMessageFor(model => model.PositionId, "", new { @class = "text-danger" })
            </div>
        </div>

Getall() and CRUD methods are called by generic repositories. The problem is exactly when I try to submit the form. Shows the error I commented earlier.

  • I just helped a friend who had this problem, in his case Viewmodel was invalid. Put a breakpoint on the line: if (ModelState.IsValid) and see which field is in error.

  • @Viniciusgrund extrintly, (Modelstate.Isvalid) is not valid. And the error it presents is An Exception of type 'System.Invalidoperationexception' occurred in System.Web.Mvc.dll but was not handled in user code Additional information: The Viewdata item that has the key 'Departamentid' is of type 'System.Int32' but must be of type 'Ienumerable<Selectlistitem>'.

  • @Viniciusgrund looks down at the Model img

Browser other questions tagged

You are not signed in. Login or sign up in order to post.