【问题标题】:Partial Create view with ViewModel has a data type mismatch使用 ViewModel 的部分创建视图具有数据类型不匹配
【发布时间】:2014-03-21 17:18:29
【问题描述】:

我正在使用 ViewModel 进行创建操作,它由一个类型为 Device 的实体和两个 IEnumerable<SelectListItem> 组成,用于在创建新项目时填充 2 个下拉列表。

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);
}

这本身并没有什么问题,因为我可以很好地创建、阅读和更新所有内容。 现在我想更新我的索引视图以保存部分创建视图。在页面的右侧,应该有与独立视图中相同的创建表单。

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

现在运行它时,我收到以下错误(免费翻译):

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

Index 视图呈现并想要调用设备控制器中的 Create 方法。 Create 方法实例化一个新的DeviceEditViewModel 并填充两个IEnumerable&lt;SelectListItem&gt;。为什么这在部分视图中失败,但在常规视图中却没有 - 我该如何解决这个问题?

更新 林的回答并不完全正确,但让我走上了正确的道路——在我的世界里,这被视为一个赞成票和一个接受作为答案。

我所做的是创建了一个 DeviceIndexViewModel,其中包含创建/编辑设备所需的 EditViewModel。

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

现在需要相应地更新索引操作:

    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);
    }

现在我可以调用 PartialView 了:

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

最后告诉partialView调用特定的方法:

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

谢谢

【问题讨论】:

  • 同一页面上是否还有其他视图模型?我遇到了这个问题,我的 @Html.DropDownList 或我的视图模型没有任何问题。
  • 是的,索引视图被强类型化为模型IEnumerable&lt;Device&gt;

标签: asp.net-mvc razor partial-views asp.net-mvc-5


【解决方案1】:

您需要像下面那样创建DeviceEditViewModel,然后在您的Index 视图中将其用作强类型视图,然后将对象DropDownListViewModel 传递给您的局部视图。

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; }
}

将对象 DropDownListViewModel 传递给您的局部视图

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

更改您的Create 操作方法,如下所示:

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);
        }

你的部分观点:

@model DropDownListViewModel

@Html.DropDownListFor(n => n.SelectedManufactor, Model.ManufactorListItems)    
@Html.DropDownListFor(n => n.SelectedCategory, Model.CategoriesListItems)

【讨论】:

  • 想详细说明一下?当我真正想创建设备时,我不明白如何将DropdownViewModel 传递给视图。下拉项目只是为了确保用户不会输入一些虚构的公牛***。
  • 如果您使用 RenderAction,您可以在控制器中新建视图模型并将其传递给视图.. return("MyView",mymodel)
  • 林有道理。但是,我明天将不得不执行此操作。今天的时间到了。
  • Lin 我发现了为什么我无法理解您的解决方案:我的Index 视图使用IEnumberable&lt;Device&gt; 的模型,而我的创建模型是DeviceEditViewModel。我只是不能使用editviewmodel,因为它不支持索引视图。如果我改变它以适应它,我就不能再用它来创建设备了。我需要在这两个视图中继续使用不同的模型
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-24
  • 1970-01-01
  • 2021-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多