Я хотел бы знать, как читать JSON с макетом c Dynami в моем объекте, имеющем интерфейс IPeople
. При попытке получить сообщение об ошибке:
«Не удалось создать экземпляр типа« xxxx ». Тип - это интерфейс или абстрактный класс, и его нельзя создать.
Я потратил 2 дня на поиск в Google и попытался использовать конвертеры, и он работает только для одного объекта за раз, поэтому мне пришлось бы выбрать между преобразователем персонала и преобразователем зрителя.
Как я могу получить оба объекта для загрузки с помощью интерфейса IPeople
, который загружается в объект Staff
, если обнаружены данные персонала, и объект Spectator
, если обнаружены данные наблюдателя (возможно, больше типов объектов имеют уникальные свойства).
{
"appCore":
{
"Crowd":
[
{
"Name": "Name1",
"Staff":
{
"PopupText":
[
{ "DisplayName":"No Popup Text","PopupValue":"", "IsSeperator":false},
{ "DisplayName":"--------------","PopupValue":"", "IsSeperator":true},
{ "DisplayName":"HT","PopupValue":"HT", "IsSeperator":false}
]
},
"Spectator":
{
"PopupText2":
[
{ "DisplayName":"No Popup Text","PopupValue":"", "Cheese":"hiih"},
{ "DisplayName":"--------------","PopupValue":"", "Cheese":"hiih"},
{ "DisplayName":"Half-Time","PopupValue":"Half-Time", "Cheese":"hiih"}
]
}
}
]
}
}
C# Модели:
public class Crowd : ICrowd
{
public IPeople People { get; set; }
}
public class Staff : IPeople
{
IList<PopupTextData> PopupText { get; set; }
}
public class Spectator : IPeople
{
IList<PopupTextData2> PopupText2 { get; set; }
}
public class PopupTextData
{
public string DisplayName { get; set; }
public string PopupValue { get; set; }
public bool IsSeperator { get; set; }
}
public class PopupTextData2
{
public string DisplayName { get; set; }
public string PopupValue { get; set; }
public string Cheese { get; set; }
}
Код, используемый для чтения данных:
settings.ForEach(type =>
{
builder.Register(c => c.Resolve<MCoreReader>().LoadSection(type))
.As(type.GetInterfaces())
.AsImplementedInterfaces()
.InstancePerRequest()
.InstancePerLifetimeScope();
});
public static object LoadSection(Type type, string _configurationFilePath, string _sectionNameSuffix)
{
if (!File.Exists(_configurationFilePath))
return Activator.CreateInstance(type);
var jsonFile = File.ReadAllText(_configurationFilePath);
var section = ToCamelCase(type.Name.Replace(_sectionNameSuffix, string.Empty));
var settingsData = JsonConvert.DeserializeObject<dynamic>(jsonFile, JsonSerializerSettings);
var settingsSection = settingsData[section];
return settingsSection == null
? Activator.CreateInstance(type)
: JsonConvert.DeserializeObject(JsonConvert.SerializeObject(settingsSection), type, JsonSerializerSettings);
}
private class SettingsReaderContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var props = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Select(p => CreateProperty(p, memberSerialization))
.Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Select(f => CreateProperty(f, memberSerialization)))
.ToList();
props.ForEach(p =>
{
p.Writable = true;
p.Readable = true;
});
return props;
}
}
private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
ContractResolver = new SettingsReaderContractResolver(),
};