Mohammed Mahammed
Mohammed Mahammed

Reputation: 43

C# binding object to string

I want to bind a dynamic object to a string like replacing the instance.field in string to the real value of the instance.

See my code below to understand:

String body = "My Name is: model.Name";
Model model = new Model();
model.Name = "Mohammed";
String result = ReplaceMethod(body,model);
// result is, My Name is: Mohammed

Note: I want to use this procedure in big string value with too many fields. Thanks.

Upvotes: 1

Views: 1482

Answers (2)

Prince Owen
Prince Owen

Reputation: 1505

I created an extension based on Alexy's answer.

public static class StringExtensions
{
    public static string BindTo<T>(this string body, T model) where T : class
    {
        Regex regex = new Regex(@"{([a-zA-Z]+[0-9]*)}");

        var matches = regex.Matches(body).Cast<Match>()
            .OrderByDescending(i => i.Index);

        foreach (Match match in matches)
        {
            var fullMatch = match.Groups[0];

            var propName = match.Groups[1].Value;

            object value = string.Empty;

            try
            {
                // use reflection to get property
                // Note: if you need to use fields use GetField
                var prop = typeof(T).GetProperty(propName);

                if (prop != null)
                {
                    value = prop.GetValue(model, null);
                }
            }
            catch (Exception ex)
            {
                //TODO Logging here
            }

            // remove substring with pattern
            // use remove instead of replace, since 
            // you may have several the same string
            // and insert what required
            body = body.Remove(fullMatch.Index, fullMatch.Length)
                .Insert(fullMatch.Index, value.ToString());

        }

        return body;
    }

}

That way you can call it like this.

body = body.BindTo(model);

Edit: You could also use Mustache# which is based on the awesome mustache library.

In situations where you need much fewer properties to be bound, you could use tools like AutoMapper or create anonymous objects as you go along. For example:

body = body.BindTo(new { model.Name, model.Email });

Best of luck!

Upvotes: 0

Oleksii Klipilin
Oleksii Klipilin

Reputation: 1936

I wouldn't use perfix in string like "model.Name", I would go right away with {Name}. What we need is to find all of them, Regex can help us with this.

Try this method, check comments:

class Program
{
    static void Main(string[] args)
    {
        String body = "My Name is: {Name} {LastName}";
        Model model = new Model();
        model.Name = "Mohammed";
        model.LastName = "LastName";
        String result = ReplaceMethod(body, model);
    }

    private static string ReplaceMethod(string body, Model model)
    {
        // can't name property starting with numbers, 
        // but they are possible
        Regex findProperties = new Regex(@"{([a-zA-Z]+[0-9]*)}");

        // order by desc, since I want to replace all substrings correctly
        // after I replace one part length of string is changed 
        // and all characters at Right are moved forward or back
        var res = findProperties.Matches(body)
            .Cast<Match>()
            .OrderByDescending(i => i.Index);

        foreach (Match item in res)
        {
            // get full substring with pattern "{Name}"
            var allGroup = item.Groups[0];

            //get first group this is only field name there
            var foundPropGrRoup = item.Groups[1];
            var propName = foundPropGrRoup.Value;

            object value = string.Empty;

            try
            {
                // use reflection to get property
                // Note: if you need to use fields use GetField
                var prop = typeof(Model).GetProperty(propName);

                if (prop != null)
                {
                    value = prop.GetValue(model, null);
                }
            }
            catch (Exception ex)
            {
                //TODO Logging here
            }

            // remove substring with pattern
            // use remove instead of replace, since 
            // you may have several the same string
            // and insert what required
            body = body.Remove(allGroup.Index, allGroup.Length)
                .Insert(allGroup.Index, value.ToString());

        }

        return body;
    }

    public class Model
    {
        public string Name { get; set; }
        public string LastName { get; set; }
    }
}

Upvotes: 3

Related Questions