传递带有继承对象值的基础对象 (Json)

shl*_*chz 5 c# serialization json.net asp.net-web-api

我使用以下代码调用 WebAPI:

var client = new HttpClient
{
    BaseAddress = new Uri("http://localhost:8490/")
};
var jObject = new JObject();
jObject.Add("paramA", paramA);
jObject.Add("paramB", paramB);
JArray jArr = JArray.FromObject(paramsGenericArr);
jObject.Add("paramC", jArr);
var content = new StringContent(jObject.ToString(), Encoding.UTF8, "application/json");
var result = await client.PostAsync("api/path/tofunc", content).ConfigureAwait(false);
result.EnsureSuccessStatusCode();
Run Code Online (Sandbox Code Playgroud)

ParamsGeneric 类是一个抽象类型,具有 2 个派生类:

[DataContract]
public class ParamsTypeA : ParamsGeneric
{
    [DataMember]
    public long itemC {get; set;}
    public ParamsTypeA() :
                      base()
    {}
}

[DataContract]
public class ParamsTypeB : ParamsGeneric
{
    [DataMember]
    public long itemD {get; set;}
    public ParamsTypeB() :
                      base()
    {}
}

[DataContract]
[KnownType(typeof(ParamsTypeA))]
[KnownType(typeof(ParamsTypeB))]
public abstract class ParamsGeneric
{
    [DataMember]
    public long itemA { get; set; }
    [DataMember]
    public long itemB {get; set;}
    public ParamsGeneric() 
    {}
}
Run Code Online (Sandbox Code Playgroud)

我怀疑WebAPI中的反序列化有问题:

public class ClientData
{
    public string paramA { get; set; }
    public string paramB { get; set; }
    public ParamsGeneric[] paramC { get; set; }
}

[HttpPost]
[Route("api/path/tofunc")]
public async Task<bool> DoStuffAsync(ClientData clientData)
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

paramsGenericArr我对/有问题paramC(其类型为,并包含&ParamsGeneric[]类型的项目)ParamsTypeAParamsTypeB

WebAPI 接收一个空白数组 ( ParamsGeneric[0]) 以及其他参数。

我们将提供帮助。

更新

即使我尝试传递单个ParamsGeneric对象而不是数组,我也会收到而null不是对象。

解决方案

var serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.Auto;
JArray jArr = JArray.FromObject(paramsGenericArr, serializer);
Run Code Online (Sandbox Code Playgroud)

成功了。

cwa*_*wap 3

虽然 messages/json 中的继承绝对是可能的,但恕我直言;实在是太麻烦了:)

无论如何,您实际上可以通过设置TypeNameHandling让 Newtonsoft.Json 为您处理继承

// Allow inheritance in json payload
JsonSerializerSettings serializerSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
serializerSettings.TypeNameHandling = TypeNameHandling.All;
Run Code Online (Sandbox Code Playgroud)

.. 要不就

serializerSettings.TypeNameHandling = TypeNameHandling.Auto;
Run Code Online (Sandbox Code Playgroud)

..取决于您的需求。

这是一个简单的修复,如果它是一个内部 API 或者如果你可以保证你将始终控制客户端,那么它会很好地工作。如果您有外部客户端,我会采用“覆盖默认模型绑定器”方法,例如此处发布的“将 Json 反序列化为 Asp.Net Web API 中的派生类型”,或者非常强烈地考虑避免 API 模型中的继承。