private async Task CreateIndexIfNotExistsAsync(EntityIndexInfo indexSchema)
        {
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("api-key", _apiKey);

                var response = await client.GetAsync(this.IndexUri);

                if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    var indexModel = new IndexModel()
                    {
                        Name   = _indexName,
                        Fields = indexSchema.Properties
                                 .Select <EntityPropertyIndexInfo, Dictionary <string, object> >(p => p.IndexAttributes)
                                 .ToList <Dictionary <string, object> >()
                    };


                    var m = new HttpRequestMessage(HttpMethod.Post, this.IndexPostUri);
                    m.Content = new StringContent(JsonConvert.SerializeObject(indexModel));
                    m.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    response = await client.SendAsync(m);

                    if (!response.IsSuccessStatusCode)
                    {
                        var responseContent = await response.Content.ReadAsStringAsync();

                        throw new Exception(string.Format("Failed to created the index. ResponsePhrase: {0} /n Content: {1}", response.ReasonPhrase, responseContent));
                    }
                }
            }
        }
        private EntityIndexInfo GetEntityIndexInfo <TData>(TData entity, string action) where TData : class
        {
            var ixEntity = new EntityIndexInfo()
            {
                Action = action
            };
            var props = typeof(TData).GetProperties();

            foreach (var prop in props)
            {
                var att = prop.GetCustomAttribute <IndexableAttribute>();

                if (att != null)
                {
                    var name = att.Name;
                    if (string.IsNullOrEmpty(name))
                    {
                        name = prop.Name;
                    }

                    var ixAtt = new EntityPropertyIndexInfo()
                    {
                        Name = name.ToLower(), Value = prop.GetValue(entity), IndexDefinition = att
                    };


                    if (att.Key)
                    {
                        ixAtt.IndexAttributes.Add("name", name.ToLower());
                        ixAtt.IndexAttributes.Add("type", "Edm.String");
                        ixAtt.IndexAttributes.Add("key", "true");
                    }
                    else
                    {
                        ixAtt.IndexAttributes.Add("name", name.ToLower());
                        ixAtt.IndexAttributes.Add("type", att.Type);
                        ixAtt.IndexAttributes.Add("facetable", att.Facetable);
                        ixAtt.IndexAttributes.Add("filterable", att.Filterable);
                        ixAtt.IndexAttributes.Add("searchable", att.Searchable);
                        ixAtt.IndexAttributes.Add("sortable", att.Sortable);
                        ixAtt.IndexAttributes.Add("suggestions", att.Suggestions);
                        ixAtt.IndexAttributes.Add("retrievable", att.Retrievable);
                    }

                    ixEntity.Properties.Add(ixAtt);
                }
            }

            return(ixEntity);
        }
        private IndexDocument GetIndexDocument(EntityIndexInfo indexInfo)
        {
            var indexDoc = new IndexDocument();
            var dic      = new Dictionary <string, object>();

            dic.Add("@search.action", indexInfo.Action);

            var keyPropName = indexInfo.GetKeyPropertyName();

            foreach (var prop in indexInfo.Properties)
            {
                if (indexInfo.Action != "delete" || prop.Name == keyPropName)
                {
                    dic.Add(prop.Name, prop.Value);
                }
            }
            ;

            indexDoc.Values.Add(dic);

            return(indexDoc);
        }
        public async Task IndexDocumentAsync(EntityIndexInfo indexInfo)
        {
            await CreateIndexIfNotExistsAsync(indexInfo);

            var doc = GetIndexDocument(indexInfo);

            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("api-key", _apiKey);

                var m = new HttpRequestMessage(HttpMethod.Post, this.DocsOpsUri);
                m.Content = new StringContent(JsonConvert.SerializeObject(doc));
                m.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                var response = await client.SendAsync(m);

                if (!response.IsSuccessStatusCode)
                {
                    throw new Exception(string.Format("Failed to perform the index update for the document. Response reason phrase {0}", response.ReasonPhrase));
                }
            }
        }