-1

I am trying to share a form across multiple views using PartialView using the piece of code below:

This is the model I want to share across all views that implement the partial view

namespace CSharp.Models.ViewModels
{
   public class HomeViewModel
   {
      public string County { get; set; }
      public ElectionType? Type { get; set; }
    }
}

Partial View file looks like this:

@model CSharp.Models.ViewModels.HomeViewModel
@Html.TextBoxFor(model => model.County, new { @class = "form-control" })      
@Html.EnumDropDownListFor(model => model.Type, null, new { @class = "form-control"})

In one of the files that need to implement the partial view, I have the following code:

Home View

@model CSharp.Models.ViewModels.HomeViewModel
@using (Html.BeginForm("Index", "Result", new { ViewBag.ReturnUrl }, FormMethod.Get, new { role = "form" }))
{
   @Html.ValidationSummary(true, "", new { @class = "text-danger" })
   @Html.Partial("~/Views/Shared/_PartialViewFile.cshtml", Model)
}

When I run the page, it works as it should.

One the other page that requires the partial view, I have this view that uses a ViewModel

Manage View
@model CSharp.Models.ViewModels.HomeManageViewModel
<form >
    @Html.Partial("~/Views/Shared/_PartialViewFile.cshtml", Model.HomeViewModel);
</form>

HomeManageViewModel looks like this

public class HomeManageViewModel
{
    public HomeViewModel HomeViewModel { get; set; }
    public IndexViewModel ManageViewModel { get; set; }
}

When I run Manage View, I get this error:

The model item passed into the dictionary is of type 'HomeManageViewModel', but this dictionary requires a model item of type 'HomeViewModel'

I thought since I'm actually passing Model.HomeViewModel in Manage View partial view, it should work.

How can I pass a view model variable to partial view?

hello
  • 1,168
  • 4
  • 24
  • 59
  • The rendered partial view in `Manage View` uses `HomeViewModel` instead of `HomeManageViewModel`. You can create separate partial view for `Manage View` view which bound to `HomeManageViewModel` instead, hence partial view model should follows parent view page model. – Tetsuya Yamamoto Feb 07 '17 at 03:01
  • Side note: it is always good idea to search for error message (i.e. https://www.bing.com/search?q=c%23+The+model+item+passed+into+the+dictionary+is+of+type+but+this+dictionary+requires+a+model+item+of+type) which would have given the same explanation as nice answer by Stephen Muecke provided. – Alexei Levenkov Feb 07 '17 at 03:05

1 Answers1

5

It means that the value of property HomeViewModel in HomeManageViewModel is null - you did not initialize it in the GET method before you passed a model to the view, so its null. When the model is null, the Partial() method passes the model declared in the main view.

Either initialize HomeManageViewModel and its HomeViewModel in the GET method, and pass the model to the view

var model = new HomeManageViewModel()
{
    HomeViewModel = new HomeViewModel(){ .... }
}
return View(model);

or in the view, you can use

@Html.Partial("_PartialViewFile", new HomeViewModel());

Note however, that your code will not work in a form because a Html.Partial() will not generate the correct name prefix for model binding. Instead use an EditorTemplate. Change the name of the partial to HomeViewModel.cshtml - to match the name of the class, and place it in the Views/Shared/EditorTemplates folder (or the Views/yourControllerName/EditorTemplates folder), and then in the main view, use

@Html.EditorFor(m => m.HomeViewModel)