使用连接字符串的 DocumentDB .Net 客户端
DocumentDB .Net client using connection string
我检查了 DocumentDB 上的 MSDN for .Net (here),发现了 3 个有效的构造函数。但是 none 其中使用了连接字符串,这对我来说听起来很奇怪。
是否真的没有办法使用连接字符串而不是端点+authKey 组合来实例化客户端,或者我遗漏了什么?
例如,大多数其他 Microsoft 服务都使用此概念,即 https://docs.microsoft.com/en-us/azure/storage/storage-configure-connection-string#parsing-a-connection-string。
在我们的例子中,如果所有与 Azure 相关的东西都以相同的方式初始化,那就太棒了。只是更干净,而不是炫耀。
P.S。
请停止告诉我有关带有 Uri 和 authKey 参数的现有构造函数,问题(略有)不同。我可以按照自己提供的链接进行操作,无需帮助。谢谢
DocumentDB SDK 没有使用连接字符串的构造函数重载。它们支持使用端点 + 主密钥和端点 + permissions/resource 令牌进行初始化。
如果您想查看单个连接字符串参数,请在此处propose/upvote:https://feedback.azure.com/forums/263030-documentdb
我创建了一个 class 来解析连接字符串,类似于 CloudStorageAccount.Parse 的工作方式。我试图尽可能地遵循他们的模式,以防他们决定开源它,这有望在没有太大变化的情况下得到贡献。
public static class DocumentDbAccount
{
public static DocumentClient Parse(string connectionString)
{
DocumentClient ret;
if (String.IsNullOrWhiteSpace(connectionString))
{
throw new ArgumentException("Connection string cannot be empty.");
}
if(ParseImpl(connectionString, out ret, err => { throw new FormatException(err); }))
{
return ret;
}
throw new ArgumentException($"Connection string was not able to be parsed into a document client.");
}
public static bool TryParse(string connectionString, out DocumentClient documentClient)
{
if (String.IsNullOrWhiteSpace(connectionString))
{
documentClient = null;
return false;
}
try
{
return ParseImpl(connectionString, out documentClient, err => { });
}
catch (Exception)
{
documentClient = null;
return false;
}
}
private const string AccountEndpointKey = "AccountEndpoint";
private const string AccountKeyKey = "AccountKey";
private static readonly HashSet<string> RequireSettings = new HashSet<string>(new [] { AccountEndpointKey, AccountKeyKey }, StringComparer.OrdinalIgnoreCase);
internal static bool ParseImpl(string connectionString, out DocumentClient documentClient, Action<string> error)
{
IDictionary<string, string> settings = ParseStringIntoSettings(connectionString, error);
if (settings == null)
{
documentClient = null;
return false;
}
if (!RequireSettings.IsSubsetOf(settings.Keys))
{
documentClient = null;
return false;
}
documentClient = new DocumentClient(new Uri(settings[AccountEndpointKey]), settings[AccountKeyKey]);
return true;
}
/// <summary>
/// Tokenizes input and stores name value pairs.
/// </summary>
/// <param name="connectionString">The string to parse.</param>
/// <param name="error">Error reporting delegate.</param>
/// <returns>Tokenized collection.</returns>
private static IDictionary<string, string> ParseStringIntoSettings(string connectionString, Action<string> error)
{
IDictionary<string, string> settings = new Dictionary<string, string>();
string[] splitted = connectionString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string nameValue in splitted)
{
string[] splittedNameValue = nameValue.Split(new char[] { '=' }, 2);
if (splittedNameValue.Length != 2)
{
error("Settings must be of the form \"name=value\".");
return null;
}
if (settings.ContainsKey(splittedNameValue[0]))
{
error(string.Format(CultureInfo.InvariantCulture, "Duplicate setting '{0}' found.", splittedNameValue[0]));
return null;
}
settings.Add(splittedNameValue[0], splittedNameValue[1]);
}
return settings;
}
}
对我有用:
private static DocumentClient InitializeDocumentClient()
{
string connectionString = ConfigurationManager.AppSettings["CosmosTest"];
string[] connectionStringParts = connectionString.Split(';');
Uri clientUrl = new Uri(connectionStringParts[0].Split('=')[1]);
int keyStartPosition = connectionStringParts[1].IndexOf('=') + 1;
string clientKey = connectionStringParts[1].Substring(keyStartPosition, connectionStringParts[1].Length-keyStartPosition);
return new DocumentClient(clientUrl, clientKey, connectionPolicy);
}
实际上你可以绕道而行。
internal class CosmosDBConnectionString
{
public CosmosDBConnectionString(string connectionString)
{
// Use this generic builder to parse the connection string
DbConnectionStringBuilder builder = new DbConnectionStringBuilder
{
ConnectionString = connectionString
};
if (builder.TryGetValue("AccountKey", out object key))
{
AuthKey = key.ToString();
}
if (builder.TryGetValue("AccountEndpoint", out object uri))
{
ServiceEndpoint = new Uri(uri.ToString());
}
}
public Uri ServiceEndpoint { get; set; }
public string AuthKey { get; set; }
}
然后
var cosmosDBConnectionString = new CosmosDBConnectionString(connectionString)
var client = new DocumentClient(
cosmosDBConnectionString.ServiceEndpoint,
cosmosDBConnectionString.AuthKey)
这取自 Azure WebJobs Extensions SDK,这就是 Azure Functions V2 仅使用连接字符串的方式。省去了自己尝试解析字符串的麻烦。
我检查了 DocumentDB 上的 MSDN for .Net (here),发现了 3 个有效的构造函数。但是 none 其中使用了连接字符串,这对我来说听起来很奇怪。
是否真的没有办法使用连接字符串而不是端点+authKey 组合来实例化客户端,或者我遗漏了什么?
例如,大多数其他 Microsoft 服务都使用此概念,即 https://docs.microsoft.com/en-us/azure/storage/storage-configure-connection-string#parsing-a-connection-string。 在我们的例子中,如果所有与 Azure 相关的东西都以相同的方式初始化,那就太棒了。只是更干净,而不是炫耀。
P.S。 请停止告诉我有关带有 Uri 和 authKey 参数的现有构造函数,问题(略有)不同。我可以按照自己提供的链接进行操作,无需帮助。谢谢
DocumentDB SDK 没有使用连接字符串的构造函数重载。它们支持使用端点 + 主密钥和端点 + permissions/resource 令牌进行初始化。
如果您想查看单个连接字符串参数,请在此处propose/upvote:https://feedback.azure.com/forums/263030-documentdb
我创建了一个 class 来解析连接字符串,类似于 CloudStorageAccount.Parse 的工作方式。我试图尽可能地遵循他们的模式,以防他们决定开源它,这有望在没有太大变化的情况下得到贡献。
public static class DocumentDbAccount
{
public static DocumentClient Parse(string connectionString)
{
DocumentClient ret;
if (String.IsNullOrWhiteSpace(connectionString))
{
throw new ArgumentException("Connection string cannot be empty.");
}
if(ParseImpl(connectionString, out ret, err => { throw new FormatException(err); }))
{
return ret;
}
throw new ArgumentException($"Connection string was not able to be parsed into a document client.");
}
public static bool TryParse(string connectionString, out DocumentClient documentClient)
{
if (String.IsNullOrWhiteSpace(connectionString))
{
documentClient = null;
return false;
}
try
{
return ParseImpl(connectionString, out documentClient, err => { });
}
catch (Exception)
{
documentClient = null;
return false;
}
}
private const string AccountEndpointKey = "AccountEndpoint";
private const string AccountKeyKey = "AccountKey";
private static readonly HashSet<string> RequireSettings = new HashSet<string>(new [] { AccountEndpointKey, AccountKeyKey }, StringComparer.OrdinalIgnoreCase);
internal static bool ParseImpl(string connectionString, out DocumentClient documentClient, Action<string> error)
{
IDictionary<string, string> settings = ParseStringIntoSettings(connectionString, error);
if (settings == null)
{
documentClient = null;
return false;
}
if (!RequireSettings.IsSubsetOf(settings.Keys))
{
documentClient = null;
return false;
}
documentClient = new DocumentClient(new Uri(settings[AccountEndpointKey]), settings[AccountKeyKey]);
return true;
}
/// <summary>
/// Tokenizes input and stores name value pairs.
/// </summary>
/// <param name="connectionString">The string to parse.</param>
/// <param name="error">Error reporting delegate.</param>
/// <returns>Tokenized collection.</returns>
private static IDictionary<string, string> ParseStringIntoSettings(string connectionString, Action<string> error)
{
IDictionary<string, string> settings = new Dictionary<string, string>();
string[] splitted = connectionString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string nameValue in splitted)
{
string[] splittedNameValue = nameValue.Split(new char[] { '=' }, 2);
if (splittedNameValue.Length != 2)
{
error("Settings must be of the form \"name=value\".");
return null;
}
if (settings.ContainsKey(splittedNameValue[0]))
{
error(string.Format(CultureInfo.InvariantCulture, "Duplicate setting '{0}' found.", splittedNameValue[0]));
return null;
}
settings.Add(splittedNameValue[0], splittedNameValue[1]);
}
return settings;
}
}
对我有用:
private static DocumentClient InitializeDocumentClient()
{
string connectionString = ConfigurationManager.AppSettings["CosmosTest"];
string[] connectionStringParts = connectionString.Split(';');
Uri clientUrl = new Uri(connectionStringParts[0].Split('=')[1]);
int keyStartPosition = connectionStringParts[1].IndexOf('=') + 1;
string clientKey = connectionStringParts[1].Substring(keyStartPosition, connectionStringParts[1].Length-keyStartPosition);
return new DocumentClient(clientUrl, clientKey, connectionPolicy);
}
实际上你可以绕道而行。
internal class CosmosDBConnectionString
{
public CosmosDBConnectionString(string connectionString)
{
// Use this generic builder to parse the connection string
DbConnectionStringBuilder builder = new DbConnectionStringBuilder
{
ConnectionString = connectionString
};
if (builder.TryGetValue("AccountKey", out object key))
{
AuthKey = key.ToString();
}
if (builder.TryGetValue("AccountEndpoint", out object uri))
{
ServiceEndpoint = new Uri(uri.ToString());
}
}
public Uri ServiceEndpoint { get; set; }
public string AuthKey { get; set; }
}
然后
var cosmosDBConnectionString = new CosmosDBConnectionString(connectionString)
var client = new DocumentClient(
cosmosDBConnectionString.ServiceEndpoint,
cosmosDBConnectionString.AuthKey)
这取自 Azure WebJobs Extensions SDK,这就是 Azure Functions V2 仅使用连接字符串的方式。省去了自己尝试解析字符串的麻烦。