ASP.Net MVC Modelbinder绑定到嵌套属性

时间:2016-10-19 07:20:41

标签: c# asp.net asp.net-mvc asp.net-mvc-4

我试图在一个View / Action中处理各种模型创作。

当s / o点击"新计算机" Type ViewModel接收类型为Computer的新对象。 View切换到不同的类型(在本例中为Computer),并根据传入的模型创建View。 这工作正常,但在提交表单(调用CreateComputer Action)时,并不是整个计算机对象都被传输 - 确切地说,与计算机相关的属性(两个枚举)都会丢失。我认为这是因为下拉列表的名称不是以硬件开头,而是被称为" FormType"和" PerformanceType"相反,这种情况有适当的解决方案吗?

澄清:

模型"计算机"继承自"硬件"。因为我想用一个VM处理所有创建,更新等等/ View ViewModel有一个名为Hardware类型硬件的属性。不幸的是,当使用VM作为Action参数时,属性Hardware始终是Hardware类型(尽管有时它应该是Computer类型)。此外,我的方法(部分)工作 - 模型绑定器似乎足够智能绑定到嵌套类型硬件。

我想要什么?

在Action中我希望Method能够确定传入的参数是Hardware类型还是类型Computer(继承表单硬件)并让Controller为确定的模型执行它的操作。换句话说:我想避免为不同的模型创建不同的动作,例如" CreateComputer(计算机计算机)"和" CreateGeneric(硬件硬件)"。

型号:

计算机:

namespace UserChange.com.Models
{
public class Computer : Hardware
    {
        public PerformanceType PerformanceType { get; set; }
        public FormType FormType { get; set; }

        public override HardwareType GetHardwareType()
        {
            return HardwareType.Computer;
        }

        public override string ToString()
        {
            return $"Computer: {base.ToString()}";
        }
    }
}

显示器:

using System.ComponentModel.DataAnnotations;

namespace UserChange.com.Models
{
    public class Monitor : Hardware
    {
        [Required]
        public short Size { get; set; }

        [Required]
        public MonitorColor MonitorColor { get; set; }

        public override HardwareType GetHardwareType()
        {
            return HardwareType.Monitor;
        }

        public override string ToString()
        {
            return "Monitor: " + base.ToString();
        }
    }
}

设备:

 [Table("NEOV_Hardware")]
public class Hardware : BaseModel
{
    [Required]
    [StringLength(50)]
    public string Description { get; set; }

    public bool IsVisible { get; set; }

    public virtual HardwareType GetHardwareType()
    {
        return HardwareType.Generic;
    }

    public override string ToString()
    {
        return Description;
    }
}

控制器:

[HttpPost]
public ActionResult CreateComputer(Computer hardware)
{
    var uow = new UnitOfWork(new ApplicationContext());
    uow.HardwareRepository.Add(hardware);
    uow.Save();
    return RedirectToAction("Index");
}

查看:

@using UserChange.com.Models
@using UserChange.dal.Repository.Interface
@model UserChange.ViewModels.NewHardwareViewModel

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@{
    switch (Model.Hardware.GetHardwareType()) {
        case HardwareType.Computer:
            <h2>New Computer</h2>
            using (Html.BeginForm("CreateComputer", "Hardware", FormMethod.Post)) {
                <table class="table table-hover table-bordered table-striped table-condensed">
                    <tr>
                        <td>Model name:</td>
                        <td>@Html.TextBoxFor(o => o.Hardware.Description)</td>
                    </tr>
                    <tr>
                        <td>Form factor:</td>
                        <td>@Html.EnumDropDownListFor(o => (o.Hardware as Computer).FormType)</td>
                    </tr>
                    <tr>
                        <td>Performance type:</td>
                        <td>@Html.EnumDropDownListFor(o => (o.Hardware as Computer).PerformanceType)</td>
                    </tr>
                    <tr>
                        <td>Comment:</td>
                        <td>@Html.TextAreaFor(o => o.Hardware.Comment)</td>
                    </tr>
                </table>
                <input type="submit" value="Submit" class="btn btn-primary" />
            }
            break;
        case HardwareType.Monitor:
            <h2>New Monitor</h2>
            using (Html.BeginForm("CreateMonitor", "Hardware", FormMethod.Post)) {
                <table class="table table-hover table-bordered table-striped table-condensed">
                    <tr>
                        <td>Model name:</td>
                        <td>@Html.TextBoxFor(o => o.Hardware.Description)</td>
                    </tr>
                    <tr>
                        <td>Size:</td>
                        <td>@Html.TextBoxFor(o => (o.Hardware as Monitor).Size)</td>
                    </tr>
                    <tr>
                        <td>Color:</td>
                        <td>@Html.EnumDropDownListFor(o => (o.Hardware as Monitor).MonitorColor)</td>
                    </tr>
                    <tr>
                        <td>Comment:</td>
                        <td>@Html.TextAreaFor(o => o.Hardware.Comment)</td>
                    </tr>
                </table>
                <input type="submit" value="Submit" class="btn btn-primary" />
            }
            break;
        case HardwareType.Generic:
            <h2>New Generic device</h2>
            using (Html.BeginForm("CreateGeneric", "Hardware", FormMethod.Post)) {
                <table class="table table-hover table-bordered table-striped table-condensed">
                    <tr>
                        <td>Model name:</td>
                        <td>@Html.TextBoxFor(o => o.Hardware.Description)</td>
                    </tr>
                    <tr>
                        <td>Comment:</td>
                        <td>@Html.TextAreaFor(o => o.Hardware.Comment)</td>
                    </tr>
                </table>
                <input type="submit" value="Submit" class="btn btn-primary" />
            }
            break;
    }
}

**编辑1:** - 缺少虚拟机

public class NewHardwareViewModel : BaseViewModel
    {
        public Hardware Hardware { get; set; }
        public NewHardwareViewModel(Hardware hardware, bool isUserAuthorized) : base(isUserAuthorized)
        {
            Hardware = hardware;
        }

        public NewHardwareViewModel(){ }
    }

0 个答案:

没有答案