c# - C# - 发布具有通用属性的模型(Web API)
问题描述
我有这种情况:
public class Dto
{
public int TypeId { get; set; }
public IType Type { get; set; }
}
public class Type1 : IType
{
public string PropertyA { get; set; }
}
public class Type2 : IType
{
public int PropertyB { get; set; }
public bool PropertyC { get; set; }
}
public class MyController : ApiController
{
[HttpPost]
public IHttpActionResult Post(Dto dto)
{
}
}
如何根据 TypeId 属性的值反序列化 IType 接口的正确实现?
我尝试使用 JsonConverter(以下示例:https ://gist.github.com/teamaton/bba69cf95b9e6766f231 ),但我只能指定一种具体类型:
public class Dto
{
public int TypeId { get; set; }
[JsonConverter(typeof(ConcreteTypeConverter<Type1>)]
public IType Type { get; set; }
}
解决方案
JsonConverter
是正确的方法,但ConcreteTypeConverter
不适合您的情况。
假设您需要根据 确定在运行时创建的具体类型TypeId
,您将需要一个JsonConverter
on Dto
not onType
属性。
尝试这个:
[JsonConverter(typeof(DtoJsonConverter))]
public class Dto
{
public IType Type { get; set; }
public int TypeId { get; set; }
}
class DtoJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Dto);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
// Load this to a JObject so that we can read TypeId
var obj = JObject.Load(reader);
var typeId = obj["TypeId"].Value<int>();
// Figure out JSON covnerter for type property based on TypeId
JsonConverter converter = null;
switch (typeId)
{
// Assuming 1 means Type1
case 1:
converter = new CreateITypeJsonConverter(() => new Type1());
break;
case 2:
converter = new CreateITypeJsonConverter(() => new Type2());
break;
}
if (converter != null)
{
serializer.Converters.Add(converter);
}
try
{
// Now create Dto and populate the object.
// This will call the JsonConverter we just added for Type property.
var dto = new Dto();
serializer.Populate(obj.CreateReader(), dto);
return dto;
}
finally
{
if (converter != null)
{
serializer.Converters.Remove(converter);
}
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException();
}
}
class CreateITypeJsonConverter : CustomCreationConverter<IType>
{
private readonly Func<IType> _factory;
public CreateITypeJsonConverter(Func<IType> factory)
{
_factory = factory;
}
public override IType Create(Type objectType)
{
return _factory();
}
}
根据的值计算DtoJsonConverter
出具体类型,并使用另一个实例化具体类型,然后填充.IType
TypeId
CreateITypeJsonConverter
Dto
您也可以TypeId
进入IType
,然后使用此问题中的一种方法:JsonConverter with Interface
推荐阅读
- vaadin - 在 Vaadin 中打开新对话框时关闭对话框
- javascript - 从角度计算滚动、俯仰和偏航
- android - 使用 AES 和 RSA 的 Android 日志加密
- .net - RabbitMQ .Net 桌面应用程序在后台任务中运行
- sql - 如何从另一个表中添加一个表中不存在于表中的列(Alter Table)
- java - 使用 postgres 索引选择从偏移到限制的所有记录
- javascript - 如何分别测试服务的每个方法?
- css - 如何在 Angular 中对齐和设置视图页面的样式
- c# - VSTO 应用程序是否可以与连接到 GSuite 帐户的 MS Outlook 一起使用?
- ios - 如何在swift5中清晰显示二维码?