C# 使用连接字符串的DocumentDB.Net客户端

C# 使用连接字符串的DocumentDB.Net客户端,c#,azure-cosmosdb,C#,Azure Cosmosdb,我检查了DocumentDB for.Net()上的MSDN,发现了3个有效的构造函数。然而,它们都没有使用连接字符串,这对我来说很奇怪 是否真的没有办法用连接字符串而不是endpoint+authKey组合来实例化客户机,或者我遗漏了什么 例如,大多数其他Microsoft服务都使用此概念,即。 在我们的例子中,如果所有与Azure相关的东西都以相同的方式初始化,那就太棒了。只是更干净,不是什么东西 附言。 请停止告诉我关于Uri和authKey参数的现有构造函数,问题(稍微)不同。我可以按照

我检查了DocumentDB for.Net()上的MSDN,发现了3个有效的构造函数。然而,它们都没有使用连接字符串,这对我来说很奇怪

是否真的没有办法用连接字符串而不是endpoint+authKey组合来实例化客户机,或者我遗漏了什么

例如,大多数其他Microsoft服务都使用此概念,即。 在我们的例子中,如果所有与Azure相关的东西都以相同的方式初始化,那就太棒了。只是更干净,不是什么东西

附言。
请停止告诉我关于Uri和authKey参数的现有构造函数,问题(稍微)不同。我可以按照我自己提供的链接,不需要帮助。谢谢。

DocumentDB SDK没有使用连接字符串的构造函数重载。它们支持使用端点+主密钥和端点+权限/资源令牌进行初始化


如果您想查看单个连接字符串参数,请在此处建议/upvote:

我创建了一个类来解析连接字符串,类似于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;
    }
}
公共静态类DocumentDbAccount
{
公共静态DocumentClient解析(字符串连接字符串)
{
文档客户端ret;
if(String.IsNullOrWhiteSpace(connectionString))
{
抛出新ArgumentException(“连接字符串不能为空”);
}
if(ParseImpl(connectionString,out-ret,err=>{throw new FormatException(err);}))
{
返回ret;
}
抛出新ArgumentException($“连接字符串无法解析为文档客户端。”);
}
公共静态bool TryParse(字符串连接字符串,out DocumentClient DocumentClient)
{
if(String.IsNullOrWhiteSpace(connectionString))
{
documentClient=null;
返回false;
}
尝试
{
返回ParseImpl(connectionString,out documentClient,err=>{});
}
捕获(例外)
{
documentClient=null;
返回false;
}
}
私有常量字符串AccountEndpointKey=“AccountEndpoint”;
私有常量字符串AccountKeyKey=“AccountKey”;
private static readonly HashSet requiresetings=new HashSet(new[]{AccountEndpointKey,AccountKeyKey},StringComparer.OrdinalIgnoreCase);
内部静态bool ParseImpl(字符串连接字符串、out DocumentClient DocumentClient、操作错误)
{
IDictionary settings=ParseStringToSettings(connectionString,错误);
如果(设置==null)
{
documentClient=空;
返回false;
}
如果(!requireResettings.IsSubsetOf(settings.Keys))
{
documentClient=null;
返回false;
}
documentClient=new documentClient(新Uri(设置[AccountEndpointKey]),设置[AccountKeyKey]);
返回true;
}
/// 
///标记输入并存储名称-值对。
/// 
///要分析的字符串。
///报告委托时出错。
///标记化集合。
私有静态IDictionary ParseStringToSettings(字符串连接字符串,操作错误)
{
IDictionary settings=新字典();
string[]splitted=connectionString.Split(新字符[]{';'},StringSplitOptions.RemoveEmptyEntries);
foreach(拆分中的字符串名称值)
{
string[]splittedNameValue=nameValue.Split(新字符[]{'='},2);
如果(splittedNameValue.Length!=2)
{
错误(“设置的格式必须为\“name=value\”);
返回null;
}
if(settings.ContainsKey(splittedNameValue[0]))
{
错误(string.Format(CultureInfo.InvariantCulture,“找到重复设置“{0}”,splittedNameValue[0]);
返回null;
}
添加(splittedNameValue[0],splittedNameValue[1]);
}
返回设置;
}
}
对我有效:

    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; }
}
然后


这是取自Azure WebJobs Extensions SDK的,这就是Azure Functions V2仅使用连接字符串的方式。省去了自己尝试解析字符串的麻烦。

每个构造函数的第一个参数是
Uri
。这就是终点。你想要什么连接字符串?@Amy,类似于我可以从Web界面获得的东西。从@ADyson,突出显示的文本(URI,键)的正下方,有主连接字符串和次连接字符串。你是说这个构造函数已经不存在了吗
this.client=newdocumentclient(新Uri(EndpointUri),PrimaryKey)@Will我不知道你为什么这么咄咄逼人,毫无帮助。我有完全相同的问题,我怀疑大多数从事Azure开发的人可能至少有一次想知道。Microsoft为Azure存储和Azure DocumentDB等提供了组合URI+密钥“连接字符串”,但您只能将其与Azure存储API一起使用。Azure DocumentDB API要求您在其他API能够将它们作为单个参数接受时提供这两个部分。我认为这是一个完全正确的问题,因为“不,没有办法”的答案是令人惊讶的,因此很有趣。发布请求后,希望它能得到肯定的答复,因为它没有制作聚合或其他改变游戏规则的东西那么多工作。我投票支持此功能。如果这是一个选项,我会自己贡献它,并且投票支持开源SDK。解析连接字符串并通过工厂创建方法(如storage AccountsHanks)调用正确的构造函数可能有多困难!这对我来说已经没有用了,但是天啊,这是冷杉
var cosmosDBConnectionString = new CosmosDBConnectionString(connectionString)
var client = new DocumentClient(
            cosmosDBConnectionString.ServiceEndpoint,
            cosmosDBConnectionString.AuthKey)