Расширение шаблона сообщения - PullRequest
2 голосов
/ 27 октября 2008

У меня есть набор шаблонов для электронных писем, которые отправляет мое приложение. В шаблоны встроены коды, соответствующие свойствам моего бизнес-объекта.

Есть ли более элегантный способ, чем звонить

string.Replace("{!MyProperty!}", item.MyProperty.ToString()) 

миллион раз? Может быть, XMLTransform, регулярные выражения или какая-то другая магия? Я использую C # 3.5.

Ответы [ 5 ]

3 голосов
/ 27 октября 2008

Прежде всего, когда я делаю это, я использую StringBuilder.Replace (), поскольку я обнаружил, что его производительность намного лучше подходит для работы с 3 или более заменами.

Конечно, есть и другие способы сделать это, но я обнаружил, что обычно не стоит дополнительных усилий пробовать другие предметы.

Возможно, вы сможете использовать Reflection, я думаю, для автоматизации замены, что может быть единственным "лучшим" способом.

2 голосов
/ 27 октября 2008
public static string Translate(string pattern, object context)
{
    return Regex.Replace(pattern, @"\{!(\w+)!}", match => {
        string tag = match.Groups[1].Value;
        if (context != null)
        {
            PropertyInfo prop = context.GetType().GetProperty(tag);
            if (prop != null)
            {
                object value = prop.GetValue(context);
                if (value != null)
                {
                    return value.ToString();
                }
            }
        }
        return "";
    });
}
Translate("Hello {!User!}. Welcome to {!GroupName!}!", new {
    User = "John",
    GroupName = "The Community"
}); // -> "Hello John. Welcome to The Community!"

https://ideone.com/D9J31c

1 голос
/ 28 октября 2008

Есть встроенный WebControl, System.Web.UI.WebControls.MailDefinition , который заменяет строки (среди прочего). Жаль, что они тесно связали его с настройками Smtp в app.config и веб-элементом управления, а затем сделали его запечатанным для предотвращения наследования.

Но он обрабатывает несколько вещей, которые вам, скорее всего, понадобятся в механизме почтовых шаблонов - основной текст из файла, html-почта, встроенные объекты и т. Д. Reflector показывает, что фактическая замена обрабатывается циклом foreach и Regex .Заменить - мне это тоже кажется разумным выбором.

Быстрый просмотр показывает, что если вы можете жить с адресом from, находящимся в app.config (вы можете впоследствии изменить его в возвращенном MailMessage), вам нужен только элемент управления владельцем для встроенных ресурсов или BodyFileName.

Если вы используете ASP.NET или можете жить с ограничениями - я бы выбрал MailDefinition. В противном случае, просто сделайте foreach над словарем и Regex.Replace. Он немного голоден из-за повторяющихся выделений тела - но они недолговечны и не должны представлять большой проблемы.

var replacements = new Dictionary<string, object>() {
    { "Property1", obj.Property1 },
    { "Property2", obj.Property2 },
    { "Property3", obj.Property3 },
    { "Property4", obj.Property4 },
}

foreach (KeyValuePair<string, object> kvp in replacement) {
    body = Regex.Replace(body, kvp.Key, kvp.Value.ToString());
}

Если у вас действительно много свойств, то сначала прочитайте свое тело с помощью Regex.Match и поразмышляйте о свойствах.

1 голос
/ 27 октября 2008

Вы можете сделать это с помощью регулярного выражения, но ваша замена регулярного выражения отличается также для каждого свойства. Я бы придерживался string.Replace.

Используйте отражение, чтобы получить свойства и заменить их в цикле:

foreach (string property in properties)
{
  string.Replace("{!"+property+"!}",ReflectionHelper.GetStringValue(item,property));
}

Просто реализуйте ваш метод ReflectionHelper.GetStringValue и используйте отражение, чтобы получить все свойства для вашего типа объекта элемента.

0 голосов
/ 29 декабря 2018

Посмотрев на ранее включенные примеры, я решил посмотреть на реальный код. @ mark-bratt Вы были ближе, чем знали.

//The guts of MailDefinition.CreateMailMessage
//from https://github.com/Microsoft/referencesource/blob/master/System.Web/UI/WebControls/MailDefinition.cs

if (replacements != null && !String.IsNullOrEmpty(body)) {
                    foreach (object key in replacements.Keys) {
                        string fromString = key as string;
string toString = replacements[key] as string;

                        if ((fromString == null) || (toString == null)) {
                            throw new ArgumentException(SR.GetString(SR.MailDefinition_InvalidReplacements));
                        }
                        // DevDiv 151177
                        // According to http://msdn2.microsoft.com/en-us/library/ewy2t5e0.aspx, some special 
                        // constructs (starting with "$") are recognized in the replacement patterns. References of
                        // these constructs will be replaced with predefined strings in the final output. To use the 
                        // character "$" as is in the replacement patterns, we need to replace all references of single "$"
                        // with "$$", because "$$" in replacement patterns are replaced with a single "$" in the 
                        // final output. 
                        toString = toString.Replace("$", "$$");
                        body = Regex.Replace(body, fromString, toString, RegexOptions.IgnoreCase);
                    }
                }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...