Ich bin derzeit mit der Situation konfrontiert, wo ich eine JSON-Datei, die ich nicht ändern kann, und ich möchte die resultierende deserialized-Klasse für Designzwecke generisch sein.Wie Deserialisierung der Auflistung von Schnittstellen, wenn konkrete Klassen andere Schnittstellen enthält
Zuerst sind hier meine Schnittstellen:
public interface IJobModel
{
string ClientBaseURL { get; set; }
string UserEmail { get; set; }
ExportType Type { get; set; }
List<IItemModel> Items { get; set; }
}
public interface IItemModel
{
string Id { get; set; }
string ImageSize { get; set; }
string ImagePpi { get; set; }
List<ICamSettings> CamSettings { get; set; }
}
public interface ICamSettings
{
string FileName { get; set; }
}
hier Dann ist der Code Ich entwerfe mein Problem zu lösen:
public class ThumbnailJobModel : IJobModel
{
[JsonProperty("clientBaseURL")]
public string ClientBaseURL { get; set; }
[JsonProperty("userEmail")]
public string UserEmail { get; set; }
[JsonProperty("type")]
[JsonConverter(typeof(TypeConverter))]
public ExportType Type { get; set; }
[JsonProperty("items")]
[JsonConverter(typeof(ConcreteConverter<List<IItemModel>, List<Item>>
))]
public List<IItemModel> Items { get; set; }
public ThumbnailJobModel()
{
Type = ExportType.Thumbnails;
Items = new List<IItemModel>();
}
public class Item : IItemModel
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("imageSize")]
public string ImageSize { get; set; }
[JsonProperty("imagePpi")]
public string ImagePpi { get; set; }
[JsonProperty("shoots")]
//[JsonConverter(typeof(CamSettingsConverter))]
[JsonConverter(typeof(ConcreteConverter<List<ICamSettings>,
List<ShootSettings>>))]
public List<ICamSettings> CamSettings { get; set; }
public Item()
{
CamSettings = new List<ICamSettings>();
}
}
public class ShootSettings : ICamSettings
{
[JsonProperty("orientation")]
[JsonConverter(typeof(OrientationConverter))]
public Orientation Orientation { get; set; }
[JsonProperty("clothShape")]
[JsonConverter(typeof(ClothShapeConverter))]
public Shape Shape { get; set; }
[JsonProperty("fileName")]
public string FileName { get; set; }
public ShootSettings()
{
Orientation = Orientation.Perspective;
Shape = Shape.Folded;
FileName = null;
}
}
public enum Orientation
{
Perspective = 0,
Oblique = 1,
Front = 2,
Back = 3,
Left = 4,
Right = 5,
Up = 6,
Down = 7
}
public enum Shape
{
Folded = 0,
Hanger = 1,
Mannequin = 2
}
public class ConcreteConverter<I, T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(I) == objectType;
}
public override object ReadJson(JsonReader reader,
Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<T>(reader);
}
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public class OrientationConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
string enumString = (string)reader.Value;
return Enum.Parse(typeof(Orientation), enumString, true);
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public class ClothShapeConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
var enumString = (string)reader.Value;
return Enum.Parse(typeof(Shape), enumString, true);
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public class TypeConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
return ExportType.Thumbnails;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public static void HandleDeserializationError(object sender,
ErrorEventArgs errorArgs)
{
errorArgs.ErrorContext.Handled = true;
var currentObj = errorArgs.CurrentObject as ShootSettings;
if (currentObj == null) return;
currentObj.Orientation = Orientation.Perspective;
currentObj.Shape = Shape.Folded;
}
}
Wie man dort sehen kann eine Liste von ICamSettings
in der IItemModel
Schnittstelle .
ich versuchen, diese json in meine ThumbnailJobModel
Klasse deserialisieren:
{
"clientBaseURL":"https://clientName.fr",
"userEmail":"[email protected]",
"items":[
{
"id":"11913",
"imageSize":"1280,720",
"imagePpi":"72",
"shoots":[
{
"fileName":"front1.png",
"orientation":"front",
"clothShape":"hanger"
},
{
"fileName":"folded1.png",
"orientation":"front",
"clothShape":"folded"
},
{
"fileName":"right1.png",
"orientation":"right",
"clothShape":"hanger"
}
]
},
{
"id":"2988",
"imageSize":"1280,720",
"imagePpi":"",
"shoots":[
{
"fileName":"perspective1.png",
"orientation":"perspective"
}
]
}
]
}
ich deserialisieren meine Json wie folgt aus:
//Read the job config
string jobConfig = File.ReadAllText(jsonConfigPath);
IJobModel m_jobModel = JsonConvert.DeserializeObject<ThumbnailJobModel>(
jobConfig);
Und die folgende Ausnahme ausgelöst:
Exception : Error setting value to 'CamSettings' on
'IWD.Screenshoter.Job.ThumbnailJobModel+Item'.
Stack :
at Newtonsoft.Json.Serialization.DynamicValueProvider.SetValue
(System.Object target, System.Object value) [0x00000] in <filename
unknown>:0
at
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue
(Newtonsoft.Json.Serialization.JsonProperty property,
Newtonsoft.Json.JsonConverter propertyConverter,
Newtonsoft.Json.Serialization.JsonContainerContract containerContract,
Newtonsoft.Json.Serialization.JsonProperty containerProperty,
Newtonsoft.Json.JsonReader reader, System.Object target) [0x00000] in
<filename unknown>:0
at
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject
(System.Object newObject, Newtonsoft.Json.JsonReader reader,
Newtonsoft.Json.Serialization.JsonObjectContract contract,
Newtonsoft.Json.Serialization.JsonProperty member, System.String id)
[0x00000] in <filename unknown>:0
Ich verstehe ehrlich gesagt nicht, was ich falsch mache, ich hoffe, dass jemand in der Lage sein wird, durchzudrehen w ein Licht darauf.
Hallo dbc, tut mir wirklich leid für die Verzögerung:/ Super einfach zu verstehen und absolut brillante Lösung, es funktioniert wie ein Charme! Vielen Dank. –