【问题标题】:Dynamic type model binding in ASP.NET CoreASP.NET Core 中的动态类型模型绑定
【发布时间】:2018-04-23 22:26:06
【问题描述】:

我目前正在开发可用于多种类型内容的内容编辑器,开发人员可以在其中指定自己的模型。例如,模型可能如下所示:

public class ImageWithCopyWidgetModel : WidgetModel, IWidgetModel
{
    public string ImageUrl { get; set; }
    public string ImageAltText { get; set; }

    public string HeaderText { get; set; }

    public string BodyContent { get; set; }
}

在编辑器方面,我有一个看起来像这样的视图模型:

public class EditContentViewModel<TModel> where TModel : IWidgetModel
{
    public int Id { get; set; }
    public string Name { get; set; }

    public TModel WidgetModel { get; set; }
}

我在 GET/form 显示端的绑定工作正常。我的问题是让模型绑定器接受POST 上的数据?我尝试了以下方法,但每个都为model.WidgetModel 返回null

// Option 1
EditContent(int pageId, int id, EditContentViewModel<dynamic> model)

// Option 2
EditContent(int pageId, int id, EditContentViewModel<object> model)

// Option 3
EditContent(int pageId, int id, EditContentViewModel<IWidgetModel> model)

请注意,出于测试目的,我尝试将WidgetModel 的类型显式设置为具体类(上面提到的ImageWithCopyWidgetModel),这样就可以了。

我真的想避免在此处使用 Request.Form,因为它会限制此实施的未来计划。

【问题讨论】:

  • 问题是当您将模型发布到 api 时 - 模型类型(通常)不会在任何地方编码。您通常会发布类似:{Id: 1, Name: "name", WidgetModel: {... }} 的内容,但(通常)不可能从该信息中推断出您的模型类型。

标签: c# asp.net-core model-binding


【解决方案1】:

您想要的东西是不可能的,至少开箱即用。在帖子中,modelbinder 所拥有的只是一堆键值对字符串。决定如何将这些值绑定到有用的东西是动作参数。具体来说,当您绑定到EditContentViewModel 时,它无法知道它应该实际上创建ImageWithCopyWidgetModel 的实例。

此外,modelbinder 旨在丢弃它不知道如何处理的值。这意味着不幸的是,事后甚至不可能转换为ImageWithCopyWidgetModel,因为到那时EditCopyViewModel 上不存在的所有属性都将被丢弃。

您最好的选择是自定义模型绑定器,但它的实现对于 Stack Overflow 的范围来说过于广泛。建议你参考documentation

【讨论】:

  • 谢谢@chris-pratt。我担心可能是这种情况。我将看看如何构建自定义模型绑定器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-14
  • 2023-02-22
  • 2017-09-21
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多