nie wiem o wszelkich biblioteki, które wykonuje to dla ciebie, ale to nie jest takie trudne, żeby go zbudować samemu.
Jeśli posiadasz swój szablon, musisz przeanalizować go jako JSON, a następnie zastąpić wszystkie symbole zastępcze rzeczywistymi wartościami. Aby to zrobić, możesz użyć wzoru gościa.
Od JSON.NET (biblioteka JSON używam) nie wydają się mieć gościa, można utworzyć jeden siebie:
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;
}
}
a następnie utworzenie wyspecjalizowanego gościa, który zastępuje symbole zastępcze rzeczywiste wartości:
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;
}
}
Użycie jest wtedy proste.Na przykład za pomocą następującego wzoru:
{
id : "$Key",
name: "$Name",
additionalInfo:
{
related: [ "$Related.Name" ]
}
}
Można użyć kodu jak poniżej:
JsonTemplateVisitor.Serialize(data, templateString)
Wynik wówczas wygląda następująco:
{
"id": "someKey",
"name": "Isaac",
"additionalInfo": {
"related": [
"Arthur"
]
}
}
Możesz też dodać jakiś błąd sprawdzanie, ale poza tym kod powinien zadziałać. Ponadto używa refleksji, więc może nie być odpowiedni, jeśli wydajność jest ważna.
Nie jest jasne, czego dokładnie chcesz. Czy chcesz utworzyć metodę, która ma ten szablon zakodowany na sztywno i działa na każdym typie, który ma 'Klucz',' Nazwa' i 'Powiązane.Nazwa'? A może chcesz kompletny system, który może zrozumieć szablony w określonym formacie i serializować je za pomocą? – svick
@ KeesC.Bakker Nikt nie jest zobowiązany do wyjaśnienia upadków, ponieważ zaniżanie jest anonimowe. Dodatkowo, to pytanie nie wykazuje żadnych wysiłków badawczych i jest niewiarygodnie niejasne (i można argumentować, że nie jest to również konstruktywne, ponieważ zasadniczo pytasz o listę produktów/przedmiotów). – casperOne
@casperOne, nie zgadzam się, że to pytanie nie jest konstruktywne. Pyta, jak wykonać jedną konkretną rzecz. Myślę, że można to rozsądnie odpowiedzieć w sposób, który pasuje do SO, przynajmniej w obecnej formie. (Zredagowałem próbkę szablonu i próbowałem wyjaśnić to jeszcze bardziej.) – svick