6

我将一个有效的 JSON 对象传递给我的 .net core 3 web api 应用程序上的控制器。这样做,我得到错误:

System.NotSupportedException:不支持接口类型的反序列化。键入“OrderTranslationContracts.OrderContracts+IImportOrderLineModel”

所以我查看了我的代码,我有一个接口的以下具体实现。这是我认为引发错误的行:

   public List<OrderContracts.IImportOrderLineModel> Lines { get; set; }

这是我传递给控制器​​的 JSON 部分:

"lines": [
        {
            "orderNumber": "LV21131327",
            "lineNumber": 1,
            "itemId": "3083US",
            "customerItemId": "3083US",
            "quantity": 3,
            "price": 0.00,
            "quantityBackOrdered": null,
            "comments": "",
            "pickLocation": "",
            "orderFilled": "O",
            "hostUom": null,
            "type": null
        }

所以我知道 JSON 是有效的。这是控制器的签名:

[HttpPost]
    public async Task<List<ImportOrderModel>> Post([FromBody] List<ImportOrderModel> orders)
    {
        var response = await _validateOrder.ValidateAllOrdersAsync(orders, null);
        return response;
    }

我什至没有闯入这段代码,因为我假设 JSON 反序列化器在尝试转换它时抛出了错误。那么我该如何克服这个错误呢?我受接口的具体实现的约束,所以如果可能的话,我无法更改我需要使用的接口。如果这不可能,是否有任何“解决方法”?

4

2 回答 2

0

HttpClient.GetFromJsonAsync 我试过了同样的问题httpClient.GetFromJsonAsync<ICustomer>(url);

我得到了错误:

不支持使用 System.Text.JSON 的接口类型的反序列化

据我所知,必须有一个模型可用于反序列化 InterfaceType。我的解决方案使用数据注释在界面中定义模型。

  1. 创建一个 TypeConverter(我在这里找到了这个类:Casting interfaces for deserialization in JSON.NET

    使用 Newtonsoft.Json;

    public class ConcreteTypeConverter<TConcrete> : JsonConverter
     {
         public override bool CanConvert(Type objectType)
         {
             //assume we can convert to anything for now
             return true;
         }
    
         public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
         {
             //explicitly specify the concrete type we want to create
             return serializer.Deserialize<TConcrete>(reader);
         }
    
         public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
         {
             //use the default serialization - it works fine
             serializer.Serialize(writer, value);
         }
     }
    

2 在您的界面中添加数据注释 ( [JsonConverter(typeof(ConcreteTypeConverter<AddressModel>))])

using Newtonsoft.Json;
public interface ICustomer
{
    int Id { get; set; }
    int Name { get; set; }

    [JsonConverter(typeof(ConcreteTypeConverter<AddressModel>))]
    IAddress Address { get; set; }
}

3 很遗憾HttpClient.GetFromJsonAsync没有使用 Newtonsoft。我写了自己的方法

public async static Task<T> GetJsonAsync<T>(HttpClient client, string url)
{
    using var response = await client.GetAsync(url);
    response.EnsureSuccessStatusCode();

    using Stream stream = await response.Content.ReadAsStreamAsync();
    using (var reader = new StreamReader(stream, Encoding.UTF8))
    {
        return JsonConvert.DeserializeObject<T>(reader.ReadToEnd(), new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Objects,
            NullValueHandling= NullValueHandling.Ignore
        });
    }
}

4 现在我可以使用:

 HttpClient httpClient= new HttpClient();
 string url="https://example.com/api/customerlist";
 var myCustomerList[]=await GetJsonAsync<CutomerModel[]>(httpClient, url);
于 2021-09-24T08:18:25.283 回答
-3

这里:

public List<OrderContracts.IImportOrderLineModel> Lines { get; set; }

您的列表是IImportOrderLineModel接口类型。

它应该像

 public List<ImportOrderLineModel> Lines { get; set; }

ImportOrderLineModel是一个实现它的类,例如:

public class ImportOrderLineModel : IImportOrderLineModel
{
    //......
}
于 2019-12-05T20:50:58.390 回答