如何在包含接口类型集合的类上应用JSON补丁文档

问题描述 投票:0回答:1

我有以下代码:

public class Customer
    {
        public string CustomerName { get; set; }

        [JsonConverter(typeof(ConcreteConverter<Order>))]
        public List<IOrderContract> Orders { get; set; }      
    }


public class Order : IOrderContract {
        public string OrderName { get; set; }
        public string OrderType { get; set; }
    }



public interface IOrderContract
    {
        string OrderName { get; set; }
        string OrderType { get; set; }
    }

当我使用以下代码应用补丁时:

 public IActionResult JsonPatchWithoutModelState([FromBody] JsonPatchDocument<Customer> patchDoc)
        {
            var customer = CreateCustomer();

            patchDoc.ApplyTo(customer);

            return new ObjectResult(customer);
        }



private Customer CreateCustomer()
        {
            return new Customer
            {
                CustomerName = "John",
                Orders = new List<IOrderContract>()
                {
                    new Order
                    {
                        OrderName = "Order0"
                    },
                    new Order
                    {
                        OrderName = "Order1"
                    }
                }
            };
        }

它抛出异常 *

值 '[ { "订单名称": "姓名", "OrderType": "type" } ]' 对于目标位置无效。

*

但是当我使用如下具体类集合而不是接口时:

public class Customer
        {
            public string CustomerName { get; set; }    

            public List<Order> Orders { get; set; }      
        }

然后就可以正常工作了。 我深入研究 jsonpatchdocument 并发现它无法为接口创建实例,这是明显的错误,即

无法创建 IOrderContract 类型的实例。类型是一个接口 或抽象类,无法实例化。

有没有其他方案可以实现接口的补丁转换?

json patch webapi json-patch
1个回答
0
投票

我是这样解决的:

创建了一个 ContractResolver

public class InterfacesContractResolver : DefaultContractResolver
    {

        public static readonly InterfacesContractResolver Instance = new InterfacesContractResolver();

        private InterfacesContractResolver() { }

        public override JsonContract ResolveContract(Type type)
        {
            if (type == typeof(IOrderContract)) return base.ResolveContract(typeof(Order));
            return base.ResolveContract(type);
        }

    }

然后,在应用补丁之前,将 ContractResolver 设置为您的 InterfacesContractResolver

public IActionResult JsonPatchWithoutModelState([FromBody] JsonPatchDocument<Customer> patchDoc)
    {
        var customer = CreateCustomer();

        //set the contractResolver
        patchDoc.ContractResolver = InterfacesContractResolver.Instance;

        patchDoc.ApplyTo(customer);

        return new ObjectResult(customer);
    }
© www.soinside.com 2019 - 2024. All rights reserved.