Non so di qualsiasi libreria che fa per voi, ma non è così difficile da costruire da soli.
Se si dispone del modello, è necessario analizzarlo come JSON e quindi sostituire tutti i segnaposto con valori effettivi. Per fare ciò, puoi usare il modello visitatore.
Dal JSON.NET (la libreria JSON che sto usando) non sembrano avere un visitatore, è possibile creare uno voi stessi:
abstract class JsonVisitor
{
public virtual JToken Visit(JToken token)
{
var clone = token.DeepClone();
return VisitInternal(clone);
}
protected virtual JToken VisitInternal(JToken token)
{
switch (token.Type)
{
case JTokenType.Object:
return VisitObject((JObject)token);
case JTokenType.Property:
return VisitProperty((JProperty)token);
case JTokenType.Array:
return VisitArray((JArray)token);
case JTokenType.String:
case JTokenType.Integer:
case JTokenType.Float:
case JTokenType.Date:
case JTokenType.Boolean:
case JTokenType.Null:
return VisitValue((JValue)token);
default:
throw new InvalidOperationException();
}
}
protected virtual JToken VisitObject(JObject obj)
{
foreach (var property in obj.Properties())
VisitInternal(property);
return obj;
}
protected virtual JToken VisitProperty(JProperty property)
{
VisitInternal(property.Value);
return property;
}
protected virtual JToken VisitArray(JArray array)
{
foreach (var item in array)
VisitInternal(item);
return array;
}
protected virtual JToken VisitValue(JValue value)
{
return value;
}
}
e quindi creare un visitatore specializzato che sostituisce i segnaposto con valori effettivi:
class JsonTemplateVisitor : JsonVisitor
{
private readonly object m_data;
private JsonTemplateVisitor(object data)
{
m_data = data;
}
public static JToken Serialize(object data, string templateString)
{
return Serialize(
data, (JToken)JsonConvert.DeserializeObject(templateString));
}
public static JToken Serialize(object data, JToken template)
{
var visitor = new JsonTemplateVisitor(data);
return visitor.Visit(template);
}
protected override JToken VisitValue(JValue value)
{
if (value.Type == JTokenType.String)
{
var s = (string)value.Value;
if (s.StartsWith("$"))
{
string path = s.Substring(1);
var newValue = GetValue(m_data, path);
var newValueToken = new JValue(newValue);
value.Replace(newValueToken);
return newValueToken;
}
}
return value;
}
private static object GetValue(object data, string path)
{
var parts = path.Split('.');
foreach (var part in parts)
{
if (data == null)
break;
data = data.GetType()
.GetProperty(part)
.GetValue(data, null);
}
return data;
}
}
L'utilizzo è quindi semplice.Ad esempio, con la seguente configurazione:
{
id : "$Key",
name: "$Name",
additionalInfo:
{
related: [ "$Related.Name" ]
}
}
È possibile utilizzare il codice come questo:
JsonTemplateVisitor.Serialize(data, templateString)
Il risultato appare allora come questo:
{
"id": "someKey",
"name": "Isaac",
"additionalInfo": {
"related": [
"Arthur"
]
}
}
si potrebbe desiderare di aggiungere un po 'l'errore -check, ma a parte questo, il codice dovrebbe funzionare. Inoltre, utilizza la riflessione, quindi potrebbe non essere adatto se le prestazioni sono importanti.
Non è molto chiaro cosa esattamente vuoi. Vuoi creare un metodo che ha quel modello hard-coded e funziona su qualsiasi tipo che ha 'Key',' Name' e 'Related.Name'? O vuoi un sistema completo in grado di capire i modelli nel formato che hai specificato e serializzare usando questi? – svick
@ KeesC.Bakker Nessuno è richiesto per spiegare i downvotes, poiché il downvoting è anonimo. Inoltre, questa domanda non mostra alcuno sforzo di ricerca ed è incredibilmente vaga (e si può sostenere che non è costruttiva, visto che in sostanza stai chiedendo un elenco di prodotti/articoli). – casperOne
@casperOne, non sono d'accordo sul fatto che questa domanda non sia costruttiva. Si chiede come fare una cosa specifica. Penso che si possa ragionevolmente rispondere in un modo che si adatti a SO, almeno nella forma attuale. (Ho modificato il campione del template e ho provato a spiegarlo di più.) – svick