【问题标题】:JsonConverter null the whole modelJsonConverter null 整个模型
【发布时间】:2016-09-29 09:32:10
【问题描述】:

我有一个在 webApi 中使用的模型。我的模型如下。

public class Model: IModel
{
    public string Data1 { get; set; }

    public string Data2 { get; set; }

    public int DataInt { get; set; }
    [JsonConverter(typeof(JsonConcreteTypeConverter<MyObject>))]
    public List<IMyObject> DataObjects { get; set; }    
    }
}

为了反序列化该接口,我创建了自己的 jsonConverter 类,如下所示。

public class JsonConcreteTypeConverter<TConcreteType>: JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return serializer.Deserialize<TConcreteType>(reader);
    }

    public override bool CanConvert(Type objectType)
    {
        bool result;

        if (objectType == typeof(MyObject))
        {
            result = true;
        }
        else
        {
            result = false;
        }
        return result;
    }
}

这是控制器

[HttpPost]
[Route("api/{ObjectId}/Action")]
public IHttpActionResult RunAsyncAction([FromBody] Model action)
{
    IModel modelAction = action;
    //Other code
    return Content(HttpStatusCode.Accepted, OPERATION_ACCEPTED_MESSAGE);
}

我遇到的问题是,当我使用这个 jsonConverter 时,序列化程序无法反序列化模型,当我调用 webApi 时,我在 FromBody 获得的“动作”对象中得到了 null。如果我删除 JsonConverter 我得到所有正确序列化除了接口为空,因为序列化程序无法反序列化它。 Json 在调用中的格式正确。谢谢

【问题讨论】:

  • 如果您不使用提供的类型,通用转换器的意义何在?
  • @kiziu 我更正了代码,粘贴代码时出错,现在代码与问题中的一样。反序列化返回 null
  • 您在CanConvert 中仍有错误,但现在没关系。你的序列化过程有什么不寻常的地方吗?我用JsonConvert.SerializeObject 序列化了Model,它工作正常(我刚刚创建了一些虚拟的IMyObjectMyObject)。我现在还可以说的是,您的 JsonConverter 不会按您的计划工作 - 它不适用于集合中的项目,但适用于整个集合(适用于标记有属性的属性)。
  • @kiziu 序列化工作正常。我的问题是反序列化。 serializer.Deserialize(reader);它总是返回 null
  • 好吧,你说序列化也不起作用。我将进一步研究反序列化。

标签: c# json serialization asp.net-web-api


【解决方案1】:

您的JsonConverter 的实现没有按预期工作,因为您的ReadJson() 正在尝试从reader 反序列化单个实例,但实际上reader 位于ArrayStart 的位置,所以这意味着该转换器应该处理整个数组的反序列化,而不仅仅是单个项目。换句话说 - JsonConverter 必须处理装饰成员类型的反序列化。

在您的情况下,您希望转换器用于数组项。要使其正常工作,您需要使用不同的属性 - JsonProperty,以及它的属性 ItemConverterType。结果应该是这样的:

[JsonProperty(ItemConverterType = typeof(JsonConcreteTypeConverter<MyObject>))]
public List<IMyObject> DataObjects { get; set; }

这将在反序列化项目而不是整个数组时正确应用您的转换器。

另外,如果您可以详细说明,如果您的反序列化器只能处理它的一种实现,那么在 Model 中具有接口有什么意义?

您还应该更正这个条件if (objectType == typeof(MyObject)) - 它应该使用TConcreteType

PS。关于 cmets - 最初我想让JsonConverter 与列表一起使用,因为我忘记了JsonProperty.ItemConverterType,在你的情况下这是正确的方法。

【讨论】:

  • 我在模型中有接口,因为我们对该接口有多个实现。我正在以迭代方式开发我的 webApi,第一个实现仅支持该类型。在我接下来的步骤中,它将支持更多类型。感谢您抽出宝贵时间,它工作正常
猜你喜欢
  • 2021-10-03
  • 2019-07-03
  • 1970-01-01
  • 2011-12-16
  • 2021-03-30
  • 2015-08-10
  • 1970-01-01
  • 2021-12-03
  • 2012-02-18
相关资源
最近更新 更多