DocumentDB .Net client using connection string

后端 未结 4 1602
野性不改
野性不改 2021-01-17 14:37

I checked the MSDN on DocumentDB for .Net (here) and found 3 valid constructors. However none of them makes use of connection strings, which sounds strange for me.

I

相关标签:
4条回答
  • 2021-01-17 15:16

    The DocumentDB SDKs do not have constructor overloads using connection strings. They support initializing with endpoint + master key, and endpoint + permissions/resource tokens.

    If you'd like to see a single connection string argument, please propose/upvote here: https://feedback.azure.com/forums/263030-documentdb

    0 讨论(0)
  • 2021-01-17 15:16

    That works for me:

        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);
        }
    
    0 讨论(0)
  • 2021-01-17 15:17

    You can actually do this in a roundabout way.

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

    Then

    var cosmosDBConnectionString = new CosmosDBConnectionString(connectionString)
    var client = new DocumentClient(
                cosmosDBConnectionString.ServiceEndpoint,
                cosmosDBConnectionString.AuthKey)
    

    This is taken from the Azure WebJobs Extensions SDK, which is how Azure Functions V2 is able to work with just a connection string. Saves having to try and parse the string yourself.

    0 讨论(0)
  • 2021-01-17 15:34

    I created a class for parsing connection string similar to how the CloudStorageAccount.Parse works. I tried to follow their pattern as closely as possible in case they ever decide to open source it, this could hopefully be contribed without much change.

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题