RicoSuter/NSwag

Arrays of nullable types in DTO properties can't read JSON null

Open

#2,412 创建于 2019年9月19日

在 GitHub 查看
 (3 评论) (0 反应) (0 负责人)C# (1,189 fork)batch import
help wantedproject: NSwag.Core

仓库指标

Star
 (6,291 star)
PR 合并指标
 (30 天内没有已合并 PR)

描述

In short

DTO classes containing collections of nullable types is not created with the correct types in the generated client-code and having an incorrect JsonProperty attribute. Specifically a collection of nullable integers will be generated as ObservableCollection<int> with the attributes NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore instead of NullValueHandling.Include

Details

I have created a WEB API and have for some time been creating my client library with NSwagStudio from the compiled assembly. Today I tried to add a new route to the API which returns a List<HistoryDataRow>.

Each element looks something like this:

public class HistoryDataRow
{
	public DateTime LogTime { get; set; }
	public short?[] DataPoints { get; set; }

	public HistoryDataRow()
	{
		DataPoints = new short?[100];
	}
}

The api works fine when testing with a rest tool which shows that the API is capable of returning null values in the array DataPoints in the JSON response.

However when creating the client with NSwagStudio the DTO contains a property called DataPoints which is defined like this:

[Newtonsoft.Json.JsonProperty("DataPoints", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public System.Collections.ObjectModel.ObservableCollection<int> DataPoints
{
  ...   
}

In order to get the client to accept null-values in the array I have to change the generated code to

[Newtonsoft.Json.JsonProperty("DataPoints", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Include)]
public System.Collections.ObjectModel.ObservableCollection<int?> DataPoints
{
  ...   
}

Notice that the attribute JsonProperty is now called with NullValueHandling = Newtonsoft.Json.NullValueHandling.Include and the collection is now of nullable int.

This might be related to #2116 or code wise be in the same area, but I cannot easily verify this.

Edit: I forgot to mention what the resulting effect is... When the client receives an array containing values of null I get the following exception:

Exception: {"Could not deserialize the response body stream as System.Collections.ObjectModel.ObservableCollection`1[[Scc_Client.ApiClients_v1_0.HistoryDataRow, SCC-Client, Version=1.1.1.626, Culture=neutral, PublicKeyToken=null]].\n\nStatus: 200\nResponse: \n"}

InnerException {"Error converting value {null} to type 'System.Int32'. Path '[0].DataPoints[30]', line 1, position 184."} | System.Exception {Newtonsoft.Json.JsonSerializationException}

贡献者指南