Deserialisieren von JSON, das eine eingebettete JSON-Zeichenfolge enthält

Deserialisieren von JSON, das eine eingebettete JSON-Zeichenfolge enthält

Wenn Sie Post versenden, stecken Sie einen Brief in einen Umschlag und bringen Routing-Informationen auf dem Umschlag an. Der Postdienst verwendet die Routing-Informationen, um den Umschlag an eine bestimmte Mailbox zu liefern. Der Briefkastenbesitzer öffnet dann den Umschlag und liest den Brief.

Manchmal müssen Sie sich möglicherweise mit dem JSON-Äquivalent dieses Szenarios befassen. Möglicherweise haben Sie eine JSON-Nachricht mit Routing-Informationen und einer eingebetteten JSON-Zeichenfolge.

Eine Verwendung davon ist, wenn Sie eine Plugin-Architektur verwenden. Der Dienst, der die Plugins geladen hat, kann JSON-Nachrichten empfangen und das eingebettete JSON zur weiteren Verarbeitung an das entsprechende Plugin weiterleiten.

In diesem Artikel zeige ich ein Codebeispiel, das die Deserialisierung von JSON handhabt, das eine eingebettete JSON-Zeichenfolge enthält.

Generieren des JSON-Umschlags

Das Folgende ist ein Beispiel für einen JSON-Umschlag:

{
	"To": "PaymentProcessor",
	"Payload": "{\"Id\":\"1\",\"Amount\":20.21}"
}
Code language: JSON / JSON with Comments (json)

Es enthält Routing-Informationen und eine eingebettete JSON-Zeichenfolge. Das einzige Besondere am eingebetteten JSON ist, dass es maskiert/codiert wurde.

Dieser JSON wurde durch Serialisierung der folgenden Klasse generiert:

public class JsonEnvelope
{
	public string To { get; set; }
	public string Payload { get; set; }
}
Code language: C# (cs)

Der Absender generiert diesen JSON-Umschlag, indem er zuerst die Nutzlast und dann den Umschlag wie folgt serialisiert:

var jsonEnvelope = new JsonEnvelope()
{
	To = "PaymentProcessor",
	Payload = JsonSerializer.Serialize(new Payment()
	{
		Id = "1",
		Amount = 20.21m
	})
};

var jsonToSend = JsonSerializer.Serialize(jsonEnvelope, options);
Code language: C# (cs)

Routing des JSON-Umschlags

Der Absender sendet den JSON-Umschlag an einen Dienst. Der Dienst enthält eine Routenkarte, die Informationen zum Weiterleiten von Nachrichten bereitstellt. Sie können die Routenkarte auf viele Arten füllen (das geht jedoch über den Rahmen dieses Artikels hinaus).

Der Dienst muss den JSON-Umschlag deserialisieren, um die Routinginformationen abzurufen. Sobald es die Routing-Informationen hat, kann es die eingebettete JSON-Zeichenfolge an den entsprechenden Prozessor weiterleiten:

public static void Route(string json)
{
	var jsonEnvelope = JsonSerializer.Deserialize<JsonEnvelope>(json);

	var processor = routeMap[jsonEnvelope.To];

	processor.Process(jsonEnvelope.Payload);
}
private static readonly Dictionary<string, IMessageProcessor> routeMap = new Dictionary<string, IMessageProcessor>();
Code language: C# (cs)

Hinweis:In diesem Beispiel werden DLL-Plugins verwendet. Innerhalb der Plugins würden sie die IMessageProcessor-Schnittstelle (siehe unten) implementieren und der Dienst würde die Prozessorobjekte in diese Karte laden. Dies ist nur eine Möglichkeit, dies zu tun. Der entscheidende Punkt ist, dass der Dienst über Informationen verfügt, die es ihm ermöglichen, die JSON-Nachricht an den entsprechenden Prozessor weiterzuleiten.

public interface IMessageProcessor
{
	void Process(string json);
}
Code language: C# (cs)

Verarbeitung der eingebetteten JSON-Zeichenfolge

Die eingebettete JSON-Zeichenfolge wird an den Prozessor übergeben. Der JSON kann dann in den entsprechenden Typ deserialisiert und verarbeitet werden. In diesem Beispiel wird der JSON an eine PaymentProcessor-Klasse übergeben, die den JSON in ein Payment-Objekt deserialisiert.

public class PaymentProcessor : IMessageProcessor
{
	public void Process(string paymentJson)
	{
		var payment = JsonSerializer.Deserialize<Payment>(paymentJson);

		Console.WriteLine($"Processing payment {payment.Id}");
	}
}
public class Payment
{
	public string Id { get; set; }
	public decimal Amount { get; set; }
}
Code language: C# (cs)