【问题标题】:@Html.EditorFor doesn't return specific types to the controller@Html.EditorFor 不会将特定类型返回给控制器
【发布时间】:2015-03-27 23:25:24
【问题描述】:

让我们假设以下简化的类结构:

public class Parent
{
    public int ID { get; set; }
}

public class ChildA : Parent
{
    public string Name { get; set; }
}

public class ChildB : Parent
{
    public DateTime Date { get; set; }
}

public class ChildC : Parent
{
    public int NumericData { get; set; }
}

public class ViewModel
{
    public List<Parent> ChildElements { get; set; }
}

如您所见,在我的视图模型中,我有一个对象列表,但这些对象可以是不同的类型。

现在,我发现编辑器模板在这种情况下运行良好 - @Html.EditorFor() 根据列表中元素的类型根据需要选择正确的编辑器。

但是,我无法将有意义的数据从用户返回到控制器。提交表单后,视图模型包含Parent 元素列表(不是特定的子类型)。更糟糕的是 - 每个 Child 类的特定属性都丢失了!

如何将子类型的所有信息返回给控制器?

【问题讨论】:

  • 据 MVC 所知,我假设问题是 public List&lt;Parent&gt; ChildElements { get; set; },在发生绑定之前,它使用父级的默认构造函数。请记住,传入数据是纯文本/文本。模型绑定器将其转换为对象的事实是为了简化工作,但如果您检查您的请求,则它都是关于没有元数据的键值,因此在处理这种情况时请记住这一点。

标签: c# model-view-controller asp.net-core-mvc


【解决方案1】:

当数据被发布到控制器时,MVC 框架处理请求数据到模型的绑定。看看this link

当它试图实例化您的 ViewModel 时,它可能正在为您的 Parent 类使用默认的无参数构造函数,并且无论发送回的实际数据如何,它都无法将其分配给属性,因为它们不存在于其中Parent 类。

您可以创建自己的custom model binder,这可能会解决您的问题。或者,您可能会在 Parent 类中创建所有属性,并使用不同的命名 EditorTemplates。

@Html.EditorFor(x => Model.Parent, "ChildATemplate")

@Html.EditorFor(x => Model.Parent, "ChildBTemplate") 

作为一般规则,坚持“一个视图,一个视图模型”是一个好主意,即使一开始感觉像是重复。它清楚地说明了从服务器发出的确切数据以及返回的确切数据。

如果“父级”表示一个复杂对象,可能是一个持久化到数据库中并与多个视图交互的对象,那么您始终可以拥有一个中间层来处理将数据从视图模型转换为复杂类。

编辑 - 回应有关调查问题的评论

为什么不接受您需要复制一些共享值并为每种问题类型创建一个类,而不是使用继承?

public class QuestionTypeA 
{
    public int ID { get; set;}
    public string Name { get; set; }
}

public class QuestionTypeB
{
    public int ID { get; set;}
    public DateTime Date { get; set; }
}

public class QuestionTypeC
{
    public int ID { get; set;}
    public int NumericData { get; set; }
}

public class ViewModel
{
    public List<QuestionTypeA> QuestionAs { get; set; }
    public List<QuestionTypeB> QuestionBs { get; set; }
    public List<QuestionTypeC> QuestionCs { get; set; }
}

【讨论】:

  • 我给出的例子被简化了。想象一下,您没有 2 或 3 种类型,而是 13 种或更多。现在您需要 13 个单独的类(具有重复的属性)、13 个列表……因为最后我需要一个有序列表,现在这些列表可能需要是字典或其他东西来跟踪顺序。就我而言,将每个问题设为特定类型而不使用继承并不是一个合理的建议。模型活页夹听起来好多了,我正在尝试。
  • 我会接受这个答案,因为创建自定义活页夹确实是要走的路。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多