【问题标题】:C# Referencing a variable type, name and value in a format stringC# 引用格式字符串中的变量类型、名称和值
【发布时间】:2020-02-17 12:31:34
【问题描述】:

我对一些生成 SQL 代码的代码有这个问题,以便以后通过数据库。 但是,当我一直在编写代码时,我心想“一定有更好的方法来做到这一点”

这是我目前得到的代码:

if (invoice.ID is string) SQL.AppendFormat($"{nameof(invoice.ID)} = '{invoice.ID}'").Replace(",", ".").Append(", ");
else SQL.AppendFormat($"{nameof(invoice.ID)} = {invoice.ID}").Replace(",", ".").Append(", ");

if (invoice.InvoiceID is string) SQL.AppendFormat($"{nameof(invoice.InvoiceID)} = {invoice.InvoiceID}, ").Replace(",", ".").Append(", "); 
else SQL.AppendFormat($"{nameof(invoice.InvoiceID)} = {invoice.InvoiceID}").Replace(",", ".").Append(", ");

if (invoice.IssuedDate is string) SQL.AppendFormat($"{nameof(invoice.IssuedDate)} = {invoice.IssuedDate}, ").Replace(",", ".").Append(", "); 
else SQL.AppendFormat($"{nameof(invoice.IssuedDate)} = {invoice.IssuedDate}").Replace(",", ".").Append(", ");

如您所见,我每次都必须引用该变量,并且我希望这段代码尽可能动态,因为我还不知道完成后会有多少列。

所以我的愿望是能够复制和粘贴一些代码,并且只更改一个或两个变量(最好是一个),如下所示:

if ({0} is string) SQL.AppendFormat($"{nameof({0})} = '{{0}}'").Replace(",", ".").Append(", ");
else SQL.AppendFormat($"{nameof({0})} = {{0}}").Replace(",", ".").Append(", ").Format(invoice.ID);

我知道上面的例子是不可能的,但我希望你能看到我想要的。

非常感谢,非常感谢任何帮助

【问题讨论】:

  • 作为一般建议,此代码非常危险(它绝对允许我使用您的 UI 控制您的数据库服务器); 非常重要从不连接用户输入来构建 SQL 查询;您使用 parameters,即where x.Foo = @foo,并将 parameter 添加到具有匹配名称和值的命令对象。
  • @MarcGravell 感谢您的输入,我将更改我的代码。但我想知道为什么这是一种危险的方法?只是为了以后可以避免。谢谢!
  • "SQL 注入";搜索“鲍比桌”;或者,考虑一下当我搜索发票123'; drop table Invoices; -- - 或者123' or 1=1; -- 时会发生什么 - SQL 注入是黑客尝试滥用您的系统的第一种方式;有一系列现成的工具专门用于自动识别和利用 SQL 注入漏洞,而攻击者无需了解或手动执行任何操作
  • 好吧,我查了“Bobby Tables”,笑得很开心,我现在明白你的意思了,在查你以前的评论的过程中,我想通了,如何使用 SQLCommand 参数我将在我的代码中使用它。我相信将来我会更加了解 SQL 漏洞,并且我认为“快速”的 google 搜索将帮助我了解黑客使用 SQL 破坏我的一天的不同方式。非常感谢您的意见。

标签: c# string variables formatting


【解决方案1】:

除了 Marc Gravell 的 cmets,您还可以有以下方面的内容:

    public class SomeInvoiceData
    {
            public int InvoiceID { get; set; }
            public System.DateTime InvoiceDate { get; set; }
            public string InvoiceName { get; set; }
    }

    public static class Value
    {
            public static string Formatted(this object o) 
            {
                    if (o is string)
                    {
                            return $"'{o.ToString()}'";
                    }
                    else if(o is DateTime)
                    {
                            return $"'{o.ToString()}'";
                    }
                    else
                    {
                            return $"{o.ToString()}";
                    }
            }
    }


    public class SQLBuilder
    {
            private List<string> List = new List<string>();
            private string Delimiter = ",";
            public void AppendAll(object instance)
            {
                    System.Reflection.PropertyInfo[] listProperty = instance.GetType().GetProperties();
                    foreach (var property in listProperty)
                    {
                            var pvalue = property.GetValue(instance);
                            var statement = $"{property.Name} = {pvalue.Formatted()}";
                            List.Add(statement);
                    }
            }
            public string Get()
            {
                    return String.Join(Delimiter, List);
            }
    }

结果是 InvoiceID = 123,InvoiceDate = '2/17/2020 10:23:04 AM',InvoiceName = '3.3 美元的发票'

【讨论】:

  • 因为这是我要求的,所以我已将其标记为解决方案。我没有使用它,因为我的程序正在生产环境中,并且需要安全:/。感谢您的意见!
  • @sbch1234 - 取决于你的数据源是什么,你可以重用上面的代码,例如,如果你需要构建 SqlParameter 的集合
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 2022-01-22
  • 2013-07-02
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
相关资源
最近更新 更多