Question

I am using a ViewModel for a create action, which consists of an entity with type Device and two IEnumerable<SelectListItem> to poulate 2 dropdownlists while creating a new item.

public class DeviceEditViewModel
{
    public Device dev { get; set; }

    public int SelectedManufactor { set; get; }
    public IEnumerable<SelectListItem> ManufactorListItems { get; set; }

    public int SelectedCategory { set; get; }
    public IEnumerable<SelectListItem> CategoriesListItems { get; set; }

}

public ActionResult Create()
{
    var vm = new DeviceEditViewModel
    {
        CategoriesListItems = repo.GetCategories().Select(x => new SelectListItem
        {
            Value = x.ID.ToString(),
            Text = x.Name
        }),
        ManufactorListItems = repo.GetManufactors().Select(x => new SelectListItem
        {
            Value = x.ID.ToString(),
            Text = x.Name
        })
    };
    return View(vm);
}

There is per se nothing wrong with that, as I can create, read and update everything just fine. Now I wanted to update my Index View to hold a partial Create View. On the right side of the page, there should be the same create form as in the standalone view.

<div class="col-lg-4">
    @{ Html.RenderPartial("_Create", new DeviceEditViewModel()); }
</div>

Now upon running this, I recieve the following error (free translation):

"SelectedManufactor" is of type "System.Int32", but requires the type "IEnumerable<SelectListItem>".

The Index view renders and wants to call the Create Method in the device controller. The Create method instanciates a new DeviceEditViewModel and populates two IEnumerable<SelectListItem>. Why does this fail in the partial View, but not in the regular View - And how can I solve this?

UPDATE Lins answer was not totally correct, but brought me on the right track - which in my world counts as an upvote and an acceptance as the answer.

What I've done is created an DeviceIndexViewModel, which holds the EditViewModel, which is needed for creating/editing Devices.

public class DeviceIndexViewModel
{
    public IEnumerable<Device> Devices { get; set; }
    public DeviceEditViewModel DeviceEditViewModel { get; set; }
}

Now the Index Action needed to be updated accordingly:

    public ActionResult Index(string searchString)
    {
        DeviceIndexViewModel vm = new DeviceIndexViewModel();
        // ...
        // omitted
        // ...
        vm.DeviceEditViewModel = new DeviceEditViewModel() 
        {
            CategoriesListItems = repo.GetCategories().Select(x => new SelectListItem
            {
                Value = x.ID.ToString(),
                Text = x.Name
            }),
            ManufactorListItems = repo.GetManufactors().Select(x => new SelectListItem
            {
                Value = x.ID.ToString(),
                Text = x.Name
            })
        };
        return View(vm);
    }

Now I could call the PartialView with:

@{ Html.RenderPartial("_Create", Model.DeviceEditViewModel); }

And finally tell the partialView to call a specific method:

@using (Html.BeginForm("Create", "Device", FormMethod.Post))
{
    // ... omitted
}

Thanks

Was it helpful?

Solution

You need to create the DeviceEditViewModel like below, then use it as strongly typed view in your Index View, then pass the object DropDownListViewModel to your partial view.

public class DeviceEditViewModel
{
    public Device dev { get; set; }

    public DropDownListViewModel DropDownListViewModels { get; set; } 
}


public class DropDownListViewModel
{
    public int SelectedManufactor { set; get; }
    public IEnumerable<SelectListItem> ManufactorListItems { get; set; }

    public int SelectedCategory { set; get; }
    public IEnumerable<SelectListItem> CategoriesListItems { get; set; }
}

Pass the object DropDownListViewModel to your partial view

@{ Html.RenderPartial("_Create", Model.DropDownListViewModels);}

Change your Create action method like below:

public ActionResult Create()
        {
            var vm = new DeviceEditViewModel
            {
                DropDownListViewModels = new DropDownListViewModel()
                {
                     CategoriesListItems = repo.GetCategories().Select(x => new SelectListItem
                        {
                            Value = x.ID.ToString(),
                            Text = x.Name
                        }),
                        ManufactorListItems = repo.GetManufactors().Select(x => new SelectListItem
                        {
                            Value = x.ID.ToString(),
                            Text = x.Name
                        })
                }
            };
            return View(vm);
        }

Your partial view:

@model DropDownListViewModel

@Html.DropDownListFor(n => n.SelectedManufactor, Model.ManufactorListItems)    
@Html.DropDownListFor(n => n.SelectedCategory, Model.CategoriesListItems)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top