如何在.NET Core中读取带有提供程序的连接字符串?

14
我已添加。
.AddJsonFile("Connections.json", optional: true, reloadOnChange: true)
 public Startup(IHostingEnvironment env)

Connections.json 包含:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=DATABASE;Trusted_Connection=True;MultipleActiveResultSets=true",
    "COR-W81-101": "Data Source=DATASOURCE;Initial Catalog=P61_CAFM_Basic;User Id=USERID;Password=PASSWORD;Persist Security Info=False;MultipleActiveResultSets=False;Packet Size=4096;",
    "COR-W81-100": "Data Source=DATASOURCE;Initial Catalog=Post_PS;User Id=USERID;Password=PASSWORD;Persist Security Info=False;MultipleActiveResultSets=False;Packet Size=4096;",
    "MSEDGEWIN10": "Data Source=DATASOURCE; Initial Catalog=COR_Basic; Persist Security Info=False;Integrated Security=true;MultipleActiveResultSets=False;Packet Size=4096;Application Name=\"COR_Basic\"",

    "server": "Data Source=DATASOURCE; Initial Catalog=COR_Basic; Persist Security Info=False;User Id=USERID;Password=PASSWORD;MultipleActiveResultSets=False;Packet Size=4096;Application Name=\"COR_Basic\""
  },


  "conStrings": [
      {
        "name": "COR-W81-101",     
        "connectionString": "Data Source=DATASOURCE; Initial Catalog=COR_Basic; Persist Security Info=False;Integrated Security=true;MultipleActiveResultSets=False;Packet Size=4096;Application Name=\"COR_Basic\"",
        "providerName": "System.Data.SqlClient"
      }

    },

    {
      "name": "server",
      "connectionString": "Data Source=DATASOURCE; Initial Catalog=COR_Basic; Persist Security Info=False;Integrated Security=true;MultipleActiveResultSets=False;Packet Size=4096;Application Name=\"COR_Basic\"",
      "providerName": "System.Data.SqlClient"
    }
  ],



  "conStringDictionary": {
    "COR-W81-101": {
      "connectionString": "Data Source=DATASOURCE; Initial Catalog=COR_Basic; Persist Security Info=False;Integrated Security=true;MultipleActiveResultSets=False;Packet Size=4096;Application Name=\"COR_Basic\"",
      "providerName": "System.Data.SqlClient"
    },

    "server": {
      "connectionString": "Data Source=DATASOURCE; Initial Catalog=COR_Basic; Persist Security Info=False;Integrated Security=true;MultipleActiveResultSets=False;Packet Size=4096;Application Name=\"COR_Basic\"",
      "providerName": "System.Data.SqlClient"
    }

  }
}

现在我想要阅读 connectionStrings:

public class ConnectionString
{
    public string name { get; set; }
    public string connectionString { get; set; }
    public string providerName { get; set; }
}

像这样:

//Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure<ConnectionString[]>(services, Configuration.GetSection("conStrings"));

// https://dev59.com/vI3da4cB1Zd3GeqP6vGO
//var objectSections = Configuration.GetSection("conStringDictionary").GetChildren();
//foreach (var x in objectSections)
//{
//    System.Console.WriteLine(x.Key);
//    var cs = new ConnectionString();
//    ConfigurationBinder.Bind(x, cs);
//    System.Console.WriteLine(cs);
//}

// http://andrewlock.net/how-to-use-the-ioptions-pattern-for-configuration-in-asp-net-core-rc2/
        Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure<Dictionary<string, ConnectionString>>(services, Configuration.GetSection("conStrings"));

但是我无法读取数组或字典。我需要每个connectionString的providerName,并且希望将其放在与连接字符串相同的条目中,但不作为连接字符串的一部分。


您的 Connections.json 文件无效。您的 "conStrings" 数组中有太多的 "}" 符号。它应该看起来像这样:http://www.jsoneditoronline.org/?id=a00f0105a65d6a651d872ea9688d6147 - M. Wiśnicki
5
兄弟,你刚刚把连接数据库的字符串发布到了公开视图中。考虑至少删除密码! - Maris
@Maris:没关系,我在发布之前已经更改了它们——只是忘记了一个,但它已经使用了TripleDES加密。数据源也不是机密的。 - user6038265
4个回答

14
你基本上已经到位了,你需要做的就是创建一些强类型类来匹配旧的 ConnectionStringSettings 并利用一些集合序列化逻辑。以下是我建议的 JSON 格式化方式,与你以前在 XML app/web.config 中指定连接字符串的方式非常相似。连接字符串的名称为键。
{
  "ConnectionStrings": {
    "Test1": {
      "ConnectionString": "server=localhost;database=db;username=user;password=pass;",
      "ProviderName": "MySql.Data.MySqlClient"
    },
    "Test2": {
      "ConnectionString": "server=localhost;database=db2;username=user2;password=pass2;",
      "ProviderName": "MySql.Data.MySqlClient"
    }
  }
}

现在需要绑定的类。首先是简单的ConnectionStringSettings类本身,实现了基本的相等性/哈希方法(因为我们打算将其放入字典中,所以这是必要的)。

public class ConnectionStringSettings
{
    public String Name { get; set; }
    public String ConnectionString { get; set; }
    public String ProviderName { get; set; }

    public ConnectionStringSettings()
    {
    }

    public ConnectionStringSettings(String name, String connectionString)
        : this(name, connectionString, null)
    {
    }

    public ConnectionStringSettings(String name, String connectionString, String providerName)
    {
        this.Name = name;
        this.ConnectionString = connectionString;
        this.ProviderName = providerName;
    }

    protected bool Equals(ConnectionStringSettings other)
    {
        return String.Equals(Name, other.Name) && String.Equals(ConnectionString, other.ConnectionString) && String.Equals(ProviderName, other.ProviderName);
    }

    public override bool Equals(Object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((ConnectionStringSettings) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hashCode = (Name != null ? Name.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ (ConnectionString != null ? ConnectionString.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ (ProviderName != null ? ProviderName.GetHashCode() : 0);
            return hashCode;
        }
    }

    public static bool operator ==(ConnectionStringSettings left, ConnectionStringSettings right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(ConnectionStringSettings left, ConnectionStringSettings right)
    {
        return !Equals(left, right);
    }
}

接下来是ConnectionStringSettings的集合。这只是必要的,因为连接字符串的名称是JSON符号中的键。为了保持那个名称一致地附加,我们需要覆盖Dictionary的Add方法(但你无法这样做,因为它不是虚拟的)。所以我们实际上只是在自己的Add实现中包装一个带有额外位的Dictionary。再次,这看起来像是很多代码,但你会发现这是非常单调乏味的东西。

public class ConnectionStringSettingsCollection : IDictionary<String, ConnectionStringSettings>
{
    private readonly Dictionary<String, ConnectionStringSettings> m_ConnectionStrings;

    public ConnectionStringSettingsCollection()
    {
        m_ConnectionStrings = new Dictionary<String, ConnectionStringSettings>();
    }

    public ConnectionStringSettingsCollection(int capacity)
    {
        m_ConnectionStrings = new Dictionary<String, ConnectionStringSettings>(capacity);
    }

    #region IEnumerable methods
    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)m_ConnectionStrings).GetEnumerator();
    }
    #endregion

    #region IEnumerable<> methods
    IEnumerator<KeyValuePair<String, ConnectionStringSettings>> IEnumerable<KeyValuePair<String, ConnectionStringSettings>>.GetEnumerator()
    {
        return ((IEnumerable<KeyValuePair<String, ConnectionStringSettings>>)m_ConnectionStrings).GetEnumerator();
    }
    #endregion

    #region ICollection<> methods
    void ICollection<KeyValuePair<String, ConnectionStringSettings>>.Add(KeyValuePair<String, ConnectionStringSettings> item)
    {
        ((ICollection<KeyValuePair<String, ConnectionStringSettings>>)m_ConnectionStrings).Add(item);
    }

    void ICollection<KeyValuePair<String, ConnectionStringSettings>>.Clear()
    {
        ((ICollection<KeyValuePair<String, ConnectionStringSettings>>)m_ConnectionStrings).Clear();
    }

    Boolean ICollection<KeyValuePair<String, ConnectionStringSettings>>.Contains(KeyValuePair<String, ConnectionStringSettings> item)
    {
        return ((ICollection<KeyValuePair<String, ConnectionStringSettings>>)m_ConnectionStrings).Contains(item);
    }

    void ICollection<KeyValuePair<String, ConnectionStringSettings>>.CopyTo(KeyValuePair<String, ConnectionStringSettings>[] array, Int32 arrayIndex)
    {
        ((ICollection<KeyValuePair<String, ConnectionStringSettings>>)m_ConnectionStrings).CopyTo(array, arrayIndex);
    }

    Boolean ICollection<KeyValuePair<String, ConnectionStringSettings>>.Remove(KeyValuePair<String, ConnectionStringSettings> item)
    {
        return ((ICollection<KeyValuePair<String, ConnectionStringSettings>>)m_ConnectionStrings).Remove(item);
    }

    public Int32 Count => ((ICollection<KeyValuePair<String, ConnectionStringSettings>>)m_ConnectionStrings).Count;
    public Boolean IsReadOnly => ((ICollection<KeyValuePair<String, ConnectionStringSettings>>)m_ConnectionStrings).IsReadOnly;
    #endregion

    #region IDictionary<> methods
    public void Add(String key, ConnectionStringSettings value)
    {
        // NOTE only slight modification, we add back in the Name of connectionString here (since it is the key)
        value.Name = key;
        m_ConnectionStrings.Add(key, value);
    }

    public Boolean ContainsKey(String key)
    {
        return m_ConnectionStrings.ContainsKey(key);
    }

    public Boolean Remove(String key)
    {
        return m_ConnectionStrings.Remove(key);
    }

    public Boolean TryGetValue(String key, out ConnectionStringSettings value)
    {
        return m_ConnectionStrings.TryGetValue(key, out value);
    }

    public ConnectionStringSettings this[String key]
    {
        get => m_ConnectionStrings[key];
        set => Add(key, value);
    }

    public ICollection<String> Keys => m_ConnectionStrings.Keys;
    public ICollection<ConnectionStringSettings> Values => m_ConnectionStrings.Values;
    #endregion
}

一些简单的扩展方法,使事情变得更简单。

public static class ConnectionStringSettingsExtensions
{
    public static ConnectionStringSettingsCollection ConnectionStrings(this IConfigurationRoot configuration, String section = "ConnectionStrings")
    {
        var connectionStringCollection = configuration.GetSection(section).Get<ConnectionStringSettingsCollection>();
        if (connectionStringCollection == null)
        {
            return new ConnectionStringSettingsCollection();
        }

        return connectionStringCollection;
    }

    public static ConnectionStringSettings ConnectionString(this IConfigurationRoot configuration, String name, String section = "ConnectionStrings")
    {
        ConnectionStringSettings connectionStringSettings;

        var connectionStringCollection = configuration.GetSection(section).Get<ConnectionStringSettingsCollection>();
        if (connectionStringCollection == null ||
            !connectionStringCollection.TryGetValue(name, out connectionStringSettings))
        {
            return null;
        }

        return connectionStringSettings;
    }
}

最后,使用方法。

var configuration = new ConfigurationBuilder()
    .AddJsonFile("config.json")
    .Build();

var connectionStrings = configuration.ConnectionStrings();

foreach (var connectionString in connectionStrings.Values)
{
    Console.WriteLine(connectionString.Name);
    Console.WriteLine(connectionString.ConnectionString);
    Console.WriteLine(connectionString.ProviderName);
}

var specificConnStr1 = connectionStrings["Test1"];
Console.WriteLine(specificConnStr1.Name);
Console.WriteLine(specificConnStr1.ConnectionString);
Console.WriteLine(specificConnStr1.ProviderName);

var specificConnStr2 = configuration.ConnectionString("Test2");
Console.WriteLine(specificConnStr2.Name);
Console.WriteLine(specificConnStr2.ConnectionString);
Console.WriteLine(specificConnStr2.ProviderName);

7

这是一个老问题,但今天我正在研究这个问题,并想分享一下...

一个简单的代替方法来包含ProviderName

这里有一个简单的替代方法,避免使用自定义扩展和更改默认的ConnectionStrings配置结构。这基于Microsoft如何在Azure上为应用程序包括ProviderName。

解决方案是在ConnectionStrings部分添加一个与上下文相关的键,该键指定ProviderName。

AppSettings.json中的SQLite提供程序:

{  
  "ConnectionStrings": {
    "MyContext": "Data Source=c:\\MySqlite.db;Version=3;",
    "MyContext_ProviderName": "System.Data.SQLite",
  }
}

然后在 C# 代码中使用 GetConnectionString() 方法读取值:

var connectionString = Configuration.GetConnectionString("MyContext");
var providerName = Configuration.GetConnectionString("MyContext_ProviderName") ?? "";

if (Regex.IsMatch(providerName, "SQLite", RegexOptions.IgnoreCase)) 
{
    builder.UseSqlite(connectionString);
}
else if (Regex.IsMatch(providerName, "Oracle", RegexOptions.IgnoreCase)) 
{    
    builder.AddOracle(connectionString);
}
else if (... 

额外内容 - 连接字符串前缀

微软为SQLClient和MySQL预定义了连接字符串前缀,这些前缀将自动以上述格式包含提供程序名称。但是,这些前缀仅在添加为环境变量时起作用,即不在appsettings.json中。例如,在launchSettings.json中使用MYSQLCONNSTR_前缀定义连接字符串将填充连接字符串和提供程序名称。有关详细信息,请参见ASP.NET Core 中的配置,然后向下滚动到连接字符串前缀

launchSettings.json

{
  "profiles": {
    "Development": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "",
      "environmentVariables": {
       "ASPNETCORE_ENVIRONMENT": "Development",

       // The prefix
       "MYSQLCONNSTR_MyContext": "Server=myServerAddress;Database=Green;Uid=myUsername;Pwd=myPassword;"

      }
    }
}

2

首先,Nicholi的回答给了我灵感!谢谢你,Nicholi。

其次,我提供了一个“列表”解决方案,而不是IDictionary解决方案。它不像IDictionary解决方案那样流畅。

这也可以被称为“如何为dot net core配置创建集合列表”

接下来是具体步骤:

首先,无耻地进行一次抄袭!

public class ConnectionStringEntry
{
    public String Name { get; set; }
    public String ConnectionString { get; set; }
    public String ProviderName { get; set; }

    public ConnectionStringEntry()
    {
    }

    public ConnectionStringEntry(String name, String connectionString)
        : this(name, connectionString, null)
    {
    }

    public ConnectionStringEntry(String name, String connectionString, String providerName)
    {
        this.Name = name;
        this.ConnectionString = connectionString;
        this.ProviderName = providerName;
    }
}

第二,一个“包装器”。我想在我的条目列表(集合)旁边跟踪DefaultConnectionStringName...。
public class ConnectionStringWrapper
{
    public string DefaultConnectionStringName { get; set; } = "";
    public List<ConnectionStringEntry> ConnectionStringEntries { get; set; } = new List<ConnectionStringEntry>();
    //public Dictionary<string, ConnectionStringEntry> ConnectionStringEntries { get; set; } = new Dictionary<string, ConnectionStringEntry>();

    public ConnectionStringEntry GetDefaultConnectionStringEntry()
    {
        ConnectionStringEntry returnItem = this.GetConnectionStringEntry(this.DefaultConnectionStringName);
        return returnItem;
    }

    public ConnectionStringEntry GetConnectionStringEntry(string name)
    {
        ConnectionStringEntry returnItem = null;
        if (null != this.ConnectionStringEntries && this.ConnectionStringEntries.Any())
        {
            returnItem = this.ConnectionStringEntries.FirstOrDefault(ce => ce.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
        }

        if (null == returnItem)
        {
            throw new ArgumentOutOfRangeException(string.Format("No default ConnectionStringEntry found. (ConnectionStringEntries.Names='{0}', Search.Name='{1}')", this.ConnectionStringEntries == null ? string.Empty : string.Join(",", this.ConnectionStringEntries.Select(ce => ce.Name)), name));
        }

        return returnItem;
    }
}

现在,我正在阅读json并将其映射到一个具体的设置对象代码:
            IConfiguration config = new ConfigurationBuilder()
                    .SetBasePath(System.IO.Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .Build();


            ConnectionStringWrapper settings = new ConnectionStringWrapper();
            config.Bind("ConnectionStringWrapperSettings", settings);
            Console.WriteLine("{0}, {1}", settings.DefaultConnectionStringName, settings.ConnectionStringEntries.Count);
            ConnectionStringEntry cse = settings.GetDefaultConnectionStringEntry();

我的NuGet包:

\.nuget\packages\microsoft.extensions.configuration\2.1.1
\.nuget\packages\microsoft.extensions.configuration.binder\2.1.1
\.nuget\packages\microsoft.extensions.configuration.json\2.1.1

以下是奖励材料:
为了支持可以部署为DotNet 4.x(“经典”?现在这个术语?)和dotnet core的代码库,我正在尝试做的一件事情之一是提供一个抽象,使得从DotNet(经典)处理连接字符串(xml,我们老朋友)到新的酷玩具:使用json的DotNetCore更加容易。
为此,我编写了一个接口:
public interface IConnectionStringWrapperRetriever
{
    ConnectionStringWrapper RetrieveConnectionStringWrapper();
}

我有一个针对dotnetcore的实现:

public class ConnectionStringWrapperDotNetCoreRetriever : IConnectionStringWrapperRetriever
{
    public const string ConnectionStringWrapperSettingsJsonElementName = "ConnectionStringWrapperSettings";

    private readonly IConfiguration config;

    public ConnectionStringWrapperDotNetCoreRetriever(IConfiguration cnfg)
    {
        this.config = cnfg;
    }

    public ConnectionStringWrapper RetrieveConnectionStringWrapper()
    {
        ConnectionStringWrapper settings = new ConnectionStringWrapper();
        this.config.Bind(ConnectionStringWrapperSettingsJsonElementName, settings);
        return settings;
    }
}

哦,是的,非常重要的JSON设置:

{
  "ConnectionStringWrapperSettings": {
    "DefaultConnectionStringName": "abc",
    "ConnectionStringEntries": [
      {
        "Name": "abc",
        "ConnectionString": "Server=myserver;Database=mydatabase;Trusted_Connection=True;MultipleActiveResultSets=true",
        "ProviderName": "SomeProvider"
      },
      {
        "Name": "def",
        "ConnectionString": "server=localhost;database=db2;username=user2;password=pass2;",
        "ProviderName": "SomeProvider"
      }
    ]
  }
}

对于DotNet(经典版),您只需要实现第二个IConnectionStringWrapperRetriever的具体内容,并进行魔法操作即可。

还记得下面的xml吗?(哈哈,它还没有那么老!)

<?xml version="1.0" encoding="utf-8"?>  
<configuration>  
  <connectionStrings>  
    <add name="ConnStr1" connectionString="LocalSqlServer: data source=127.0.0.1;Integrated Security=SSPI;Initial Catalog=aspnetdb"  
      providerName="System.Data.SqlClient" />  
  </connectionStrings>  
</configuration>  

(来自https://learn.microsoft.com/en-us/dotnet/api/system.configuration.connectionstringsettingscollection?view=netframework-4.7.2)

还记得EnterpriseLibrary中的这些内容吗?

<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</configSections>

<dataConfiguration defaultDatabase="ConnStr1"/>

我将DotNet(Classic)的实现留给读者自己完成。

现在,我将IConnectionStringWrapperRetriever注入到我的DataLayer类中。
我正在使用Dapper,所以我可以使用IConnectionStringWrapperRetriever来获取连接字符串。

如果我的项目是“house” DotNet(Classic),我注入一个版本的IConnectionStringWrapperRetriever(这里未显示,留给读者自己完成)。如果我的项目是“housed”在DotNetCore中,我注入第二个(如上所示)版本的IConnectionStringWrapperRetriever。

超出了本篇文章的范围,但是我所说的“housed”是指我有两个csproj并排放置。

MyApp.DataLayer.classic.csproj 和 MyApp.DataLayer.csproj

我发现将默认的csproj用于承载DotNetCore相关内容更容易一些。我使用“classic.csproj”文件来承载DotNet(classic)相关内容。我的程序集名称和默认命名空间仍为“MyApp.Datalayer”...... .classic仅用于csrproj文件名以区分。

我还创建了两个解决方案sln文件。MySolution.classic.sln和MySolution.sln。

看起来它正在工作......使用我上面编写的ConnectionString抽象。

我唯一的条件是在(classic)AssemblyInfo.cs文件上。

#if(!NETCOREAPP2_1)

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

/* all the other stuff removed here */

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

#endif

追加:

好的,这是DotNet(经典版)的版本:

public class ConnectionStringWrapperDotNetClassicRetriever : IConnectionStringWrapperRetriever
{
    public ConnectionStringWrapper RetrieveConnectionStringWrapper()
    {
        ConnectionStringWrapper returnItem = new ConnectionStringWrapper();

        foreach(ConnectionStringSettings css in System.Configuration.ConfigurationManager.ConnectionStrings)
        {
            ConnectionStringEntry cse = new ConnectionStringEntry(css.Name, css.ConnectionString, css.ProviderName);
            returnItem.ConnectionStringEntries.Add(cse);
        }

        if(returnItem.ConnectionStringEntries.Count == 1)
        {
            /* if there is only one, set the default name to that one */
            returnItem.DefaultConnectionStringName = returnItem.ConnectionStringEntries.First().Name;
        }
        else
        {
            /*
            <packages>
              <package id="EnterpriseLibrary.Common" version="6.0.1304.0" targetFramework="net45" />
              <package id="EnterpriseLibrary.Data" version="6.0.1304.0" targetFramework="net45" />
            </packages>                 
             */

            /* using Microsoft.Practices.EnterpriseLibrary.Data.Configuration; */
            /* You can write you own way to handle a default database, or piggyback off of EnterpriseLibrary.  You don't necessarily have to use EnterpriseLibrary.Data, you are simply piggybacking on their xml/configuration setup */
            DatabaseSettings dbSettings = (DatabaseSettings)ConfigurationManager.GetSection("dataConfiguration");
            returnItem.DefaultConnectionStringName = dbSettings.DefaultDatabase;
        }

        return returnItem;
    }
}

还有app.config xml文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <configSections>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data"/>
  </configSections>

  <connectionStrings>
    <clear/>
    <add name="MyFirstConnectionStringName" connectionString="Server=.\MyServerOne;Database=OneDB;Trusted_Connection=True;MultipleActiveResultSets=true"
      providerName="System.Data.SqlClient" />

    <add name="MySecondConnectionStringName" connectionString="Server=.\MyServerTwo;Database=TwoDB;Trusted_Connection=True;MultipleActiveResultSets=true"
      providerName="System.Data.SqlClient" />
  </connectionStrings>


  <dataConfiguration defaultDatabase="MyFirstConnectionStringName" />

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

关键词:

DotNet DotNet .Net Core Classic Json配置 ICollection 标量和集合支持dotnet和dotnetcore


0

类似于:

  var configurationRoot = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", false)
                .Build();

 var conString = configurationRoot["ConnectionStrings:MyConnection"]);

1
在 SO 上,只因没有解释就对一个可行的解决方案进行贬低投票,真是太好了。 - Derek Beattie

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