Init
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
namespace FinlyticAssets.Models.DataToObject.TradeRepublic;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
// 1. Der Response-Wrapper
|
||||
public record TradeRepublicAssetResponse(
|
||||
[property: JsonPropertyName("correlationId")] string CorrelationId,
|
||||
[property: JsonPropertyName("resultCount")] int ResultCount,
|
||||
[property: JsonPropertyName("results")] IList<TradeRepublicAsset> Results
|
||||
);
|
||||
|
||||
// 2. Das Tag-Objekt
|
||||
public record TradeRepublicTag
|
||||
{
|
||||
[JsonPropertyName("id")] public string Id { get; init; } = "";
|
||||
[JsonPropertyName("name")] public string Name { get; init; } = "";
|
||||
[JsonPropertyName("type")] public string Type { get; init; } = "";
|
||||
}
|
||||
|
||||
// 3. Die Basisklasse MIT UNSEREM CUSTOM CONVERTER (Kein [JsonPolymorphic] mehr!)
|
||||
[JsonConverter(typeof(TradeRepublicAssetConverter))]
|
||||
public record TradeRepublicAsset
|
||||
{
|
||||
[JsonPropertyName("isin")] public string Isin { get; init; } = "";
|
||||
[JsonPropertyName("name")] public string Name { get; init; } = "";
|
||||
[JsonPropertyName("type")] public string Type { get; init; } = "";
|
||||
[JsonPropertyName("instrumentCategory")] public string InstrumentCategory { get; init; } = "";
|
||||
[JsonPropertyName("hasCfd")] public bool HasCfd { get; init; }
|
||||
[JsonPropertyName("imageId")] public string? ImageId { get; init; }
|
||||
|
||||
[JsonPropertyName("tags")]
|
||||
public IReadOnlyList<TradeRepublicTag> Tags { get; init; } = Array.Empty<TradeRepublicTag>();
|
||||
}
|
||||
|
||||
// 4. Die spezifischen Klassen (inklusive Bond und Derivative aus deinem JSON!)
|
||||
|
||||
public record TradeRepublicStock : TradeRepublicAsset
|
||||
{
|
||||
[JsonPropertyName("derivativeProductCategories")]
|
||||
public IReadOnlyList<string> DerivativeProductCategories { get; init; } = Array.Empty<string>();
|
||||
}
|
||||
|
||||
public record TradeRepublicCrypto : TradeRepublicAsset
|
||||
{
|
||||
[JsonPropertyName("subtitle")] public string Subtitle { get; init; } = "";
|
||||
[JsonPropertyName("searchSubtitle")] public string SearchSubtitle { get; init; } = "";
|
||||
}
|
||||
|
||||
public record TradeRepublicEtf : TradeRepublicAsset
|
||||
{
|
||||
[JsonPropertyName("derivativeProductCategories")]
|
||||
public IReadOnlyList<string> DerivativeProductCategories { get; init; } = Array.Empty<string>();
|
||||
[JsonPropertyName("etfDescription")] public string EtfDescription { get; init; } = "";
|
||||
[JsonPropertyName("mappedEtfIndexName")] public string MappedEtfIndexName { get; init; } = "";
|
||||
[JsonPropertyName("subtitle")] public string Subtitle { get; init; } = "";
|
||||
[JsonPropertyName("searchSubtitle")] public string SearchSubtitle { get; init; } = "";
|
||||
}
|
||||
|
||||
public record TradeRepublicSynthetic : TradeRepublicAsset
|
||||
{
|
||||
[JsonPropertyName("derivativeProductCategories")]
|
||||
public IReadOnlyList<string> DerivativeProductCategories { get; init; } = Array.Empty<string>();
|
||||
}
|
||||
|
||||
// NEU: Anleihen
|
||||
public record TradeRepublicBond : TradeRepublicAsset
|
||||
{
|
||||
[JsonPropertyName("bondIssuerName")] public string BondIssuerName { get; init; } = "";
|
||||
[JsonPropertyName("searchSubtitle")] public string SearchSubtitle { get; init; } = "";
|
||||
}
|
||||
|
||||
// NEU: Derivate (Hebeleffekte etc.)
|
||||
public record TradeRepublicDerivative : TradeRepublicAsset
|
||||
{
|
||||
[JsonPropertyName("derivativeProductCategories")]
|
||||
public IReadOnlyList<string> DerivativeProductCategories { get; init; } = Array.Empty<string>();
|
||||
|
||||
[JsonIgnore]
|
||||
public string? UnderlyingIsin
|
||||
{
|
||||
get
|
||||
{
|
||||
// Wenn die ImageId z.B. "logos/US0378331005/v2" ist...
|
||||
if (!string.IsNullOrEmpty(ImageId) && ImageId.StartsWith("logos/"))
|
||||
{
|
||||
var parts = ImageId.Split('/');
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
return parts[1]; // Gibt "US0378331005" zurück
|
||||
}
|
||||
}
|
||||
return null; // Falls das Format mal anders ist
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Der Custom Converter - Die Maschine, die das JSON scannt und verteilt
|
||||
public class TradeRepublicAssetConverter : JsonConverter<TradeRepublicAsset>
|
||||
{
|
||||
public override TradeRepublicAsset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
using var doc = JsonDocument.ParseValue(ref reader);
|
||||
var root = doc.RootElement;
|
||||
|
||||
// Wir scannen nach instrumentType, egal wo im JSON es steht!
|
||||
string? instrumentType = null;
|
||||
if (root.TryGetProperty("instrumentType", out var typeElement))
|
||||
{
|
||||
instrumentType = typeElement.GetString();
|
||||
}
|
||||
|
||||
// Wir werfen das JSON gezielt in die richtige Klasse
|
||||
TradeRepublicAsset? result = instrumentType switch
|
||||
{
|
||||
"stock" => JsonSerializer.Deserialize<TradeRepublicStock>(root.GetRawText(), options),
|
||||
"crypto" => JsonSerializer.Deserialize<TradeRepublicCrypto>(root.GetRawText(), options),
|
||||
"fund" => JsonSerializer.Deserialize<TradeRepublicEtf>(root.GetRawText(), options),
|
||||
"synthetic" => JsonSerializer.Deserialize<TradeRepublicSynthetic>(root.GetRawText(), options),
|
||||
"bond" => JsonSerializer.Deserialize<TradeRepublicBond>(root.GetRawText(), options),
|
||||
"derivative" => JsonSerializer.Deserialize<TradeRepublicDerivative>(root.GetRawText(), options),
|
||||
|
||||
// Wenn TR einen Typ schickt, den wir noch nicht kennen: Fallback nutzen!
|
||||
_ => JsonSerializer.Deserialize<TradeRepublicAssetFallback>(root.GetRawText(), options)
|
||||
};
|
||||
|
||||
return result ?? new TradeRepublicAssetFallback();
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, TradeRepublicAsset value, JsonSerializerOptions options)
|
||||
{
|
||||
JsonSerializer.Serialize(writer, value, value.GetType(), options);
|
||||
}
|
||||
}
|
||||
|
||||
// Ein reiner Fallback-Record, der nur intern vom Converter genutzt wird
|
||||
file record TradeRepublicAssetFallback : TradeRepublicAsset;
|
||||
Reference in New Issue
Block a user