I deserialize a JSON which looks like this:
{
"id": "FF478946-8536-4295-AC58-F6C3D2B4E5CC",
"title": "This is a Title with an escaped variable: {VariableName}",
"weight": 50
}
To a corresponding object using Newtonsoft:
public class Event
{
public string Id { get; set; }
public string Title { get; set; }
public int Weight { get; set; }
}
And then I want to print the string Title which refers to a local string property in code. VariableName
private string VariableName { get; set; }
private Event CurrentEvent { get; set; }
public void OnNextEventClicked()
{
Log(CurrentEvent.Title);
}
I tried to somehow escape the variable with different approaches like backslash ("title": "This is a Title with an escaped variable: \"VariableName\""
) or curly brackets like in the code above but i failed... C# always treats the escaped variable as a normal part of the Title string.
What's the best way to do this? Thanks!
Like @Roman Ryzhiy pointed out in the comments, there is already a good threat about dynamic string interpolation.
The perfect solution for me was the following based on this answer.
A helper method using System.Linq.Dynamic:
public string ReplaceMacro(string value, object @object)
{
return Regex.Replace(value, @"{(.+?)}",
match => {
var p = Expression.Parameter(@object.GetType(), @object.GetType().Name);
var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, match.Groups[1].Value);
return (e.Compile().DynamicInvoke(@object) ?? "").ToString();
});
}
My full solution:
JSON:
{
"id": "FF478946-8536-4295-AC58-F6C3D2B4E5CC",
"title": "This is a Title with an escaped variable: {TitleReplacement.VariableName}",
"weight": 50
}
C#:
Data Class:
public class Event
{
public string Id { get; set; }
public string Title { get; set; }
public int Weight { get; set; }
}
Class with replacement string:
public class TitleReplacement
{
public string VariableName { get; set; }
}
Call it like:
private Event CurrentEvent { get; set; }
private TitleReplacement Replacement { get; set; }
public void OnNextEventClicked()
{
Log(ReplaceMacro(CurrentEvent.Title, Replacement);
}