在数据库中插值字符串

6
我们希望将从我们的ASP.NET Web应用程序发送的电子邮件保存在数据库中。想法是将电子邮件的格式存储在数据库中。
问题是电子邮件应包括特定于订单的信息,例如:
“感谢您的订单John Smith, 您的订单1234已收到”
我想实现的是在数据库列值中使用字符串verbatim,其中它将被存储为:
“感谢您的订单{o.customer}, 您的订单{o.id}已收到”
我很好奇是否可以在已经格式化的字符串中进行字符串插值。如果尝试使用String.Format(dbEmailString),则会抛出异常:
“System.FormatException”类型的异常发生在mscorlib.dll中,但未在用户代码中处理 附加信息:输入字符串不符合正确格式。

代码在哪里? - sstan
3个回答

10

字符串插值是一种编译时特性。您可以使用常规的String.Format来实现所需功能:

var formattedEmail = String.Format("Thank you for your order {0}, your order {1} has been received", o.customer, o.id);

如果您需要用不同的值替换多个不同占位符,也许您需要寻找一个更具动态性的模板系统。您可以使用非常基本的 String.Replace 来实现。

总之,以这种方式无法直接从存储字符串中直接引用代码中的变量 - 您需要在运行时以某种方式处理字符串。


我认为这回答了我快速提出的问题。我需要的是性质过于动态,占位符的数量可能不同。我想我应该用不同的方法解决它,可能是使用String.Replace。 - johnnyCasual
@johnnyCasual 如果你选择这种方法,你当然可以保留你已经有的完全相同的占位符,并简单地替换它们,例如:email = email.Replace("{o.customer}", o.customer) - 这样你就可以保持变量名与名称相同(如果你愿意的话)。 - James Thorpe
不要忘记使用 Regex.Replace 和 T4 Text。它们都可以在格式化字符串方面执行更强大的工作。 - iQueue

-1
在C# 6中,插值字符串表达式看起来像包含表达式的模板字符串。 它看起来像String.Format()占位符,但大括号内不是索引,而是表达式本身。
在C#6中,String.Format()看起来像是编译器在幕后处理的语法糖。
例如,在VS 2015中显示OP中的表达式:
class Program
{
    static void Main(string[] args)
    {

        dynamic order = new {customer = "Robert", id=123};
        PrintString(order);            
    }


    static void PrintString(dynamic o)
    {
        var exp1 = $"Thank you for your order { o.customer}";
        var exp2 = $"your order { o.id} has been received";
        Console.WriteLine(exp1);
        Console.WriteLine(exp2);
         
    }

}

输出结果为:

Thank you for your order Robert

your order 123 has been received

你可以从数据库中检索格式化的表达式并在其前缀加上 "$",就像上面的示例描述的那样。
在VS 2013下,你可以将新编译器安装到项目中作为nuget包: Install-Package Microsoft.Net.Compilers

4
根据上述示例,您可以从数据库检索格式化表达式并在前面加上"$"。不,您不能。静态编译时字符串(带有插值)无问题,来自数据库的动态字符串将不起作用。 - James Thorpe

-2

我想你指的是C# 6.0的新功能:https://msdn.microsoft.com/zh-cn/library/dn961160.aspx

我只是读了一些关于它的介绍,还没有实际操作过。但它应该可以使用customerid变量,至于是否能够使用对象的属性,我不确定。

string customer = o.customer; int id = o.id; string msg = $"感谢您的订购{customer},您的订单{id}已收到";

可以得到正确的结果。(需要VS 2015和.Net 4.6支持)

string msg = $"Thank you for your order {o.customer}, your order {o.id} has been received";`

可能会起作用,我没有线索。


是的,我尝试过实现这个,但问题在于我无法使用字符串msg = $dbEmailString。它不允许字符串变量使用$前缀。 - johnnyCasual
我错过了这句话:“想法是将电子邮件的格式存储在数据库中。” 插值字符串是一种编译时功能,因此在这种情况下无法使用。 - Peter Krassoi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接