问题
I am trying to run the following code:
public class Item
{
[JsonProperty(PropertyName = "api-key")]
public string apikey { get; set; }
}
[[some method]]{
var url = "https://[search service name].search.windows.net/indexes/temp?api-version=2016-09-01";
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Put,url))
{
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var sItem = new Item { apikey = [AzureSearchAdminKey] };
var tststring = JsonConvert.SerializeObject(sItem);
var body=new StringContent(tststring, Encoding.UTF8,"application/json" );
request.Content = body;
request.Method = HttpMethod.Put;
using (HttpResponseMessage response = httpClient.SendAsync(request).Result)
{
var stringr = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(stringr);
Console.ReadLine();
}
}
}
}
I get the following error: "Error reading JObject from JsonReader. Path '', line 0, position 0."
Could someone from search team tell me what I did wrong?
回答1:
The api key should be in the HTTP header, and the index definition should be in the HTTP body.
Here's some sample code for creating a data source, index, and indexer, which reads from an Azure SQL DB and indexes its rows.
class Program
{
static void Main(string[] args)
{
var searchServiceName = "[search service name]";
var apiKey = "[api key]";
var dataSourceName = "[data source name]";
var indexName = "[index name]";
var indexerName = "[indexer name]";
var azureSqlConnectionString = "[Azure SQL connection string]";
var azureSqlTableName = "[table name]";
using (var httpClient = new HttpClient())
{
var dataSourceDefinition = AzureSqlDatasourceDefinition(azureSqlConnectionString, azureSqlTableName);
var putDataSourceRequest = PutDataSourceRequest(searchServiceName, apiKey, dataSourceName, dataSourceDefinition);
Console.WriteLine($"Put data source {putDataSourceRequest.RequestUri}");
Console.WriteLine();
var putDataSourceResponse = httpClient.SendAsync(putDataSourceRequest).Result;
var putDataSourceResponseContent = putDataSourceResponse.Content.ReadAsStringAsync().Result;
Console.WriteLine(putDataSourceResponseContent);
Console.WriteLine();
var indexDefinition = IndexDefinition();
var putIndexRequest = PutIndexRequest(searchServiceName, apiKey, indexName, indexDefinition);
Console.WriteLine($"Put index {putIndexRequest.RequestUri}");
Console.WriteLine();
var putIndexResponse = httpClient.SendAsync(putIndexRequest).Result;
var putIndexResponseContent = putIndexResponse.Content.ReadAsStringAsync().Result;
Console.WriteLine(putIndexResponseContent);
Console.WriteLine();
var indexerDefinition = IndexerDefinition(dataSourceName, indexName);
var putIndexerRequest = PutIndexerRequest(searchServiceName, apiKey, indexerName, indexerDefinition);
Console.WriteLine($"Put indexer {putIndexerRequest.RequestUri}");
Console.WriteLine();
var putIndexerResponse = httpClient.SendAsync(putIndexerRequest).Result;
var putIndexerResponseContent = putIndexerResponse.Content.ReadAsStringAsync().Result;
Console.WriteLine(putIndexerResponseContent);
Console.WriteLine();
var runIndexerRequest = RunIndexerRequest(searchServiceName, apiKey, indexerName);
Console.WriteLine($"Run indexer {runIndexerRequest.RequestUri}");
Console.WriteLine();
var runIndexerResponse = httpClient.SendAsync(runIndexerRequest).Result;
Console.WriteLine($"Success: {runIndexerResponse.IsSuccessStatusCode}");
Console.ReadLine();
}
}
static HttpRequestMessage PutDataSourceRequest(string searchServiceName, string apiKey, string dataSourceName,
string datasourceDefinition)
{
var request = new HttpRequestMessage(HttpMethod.Put,
$"https://{searchServiceName}.search.windows.net/datasources/{dataSourceName}?api-version=2016-09-01");
request.Headers.Add("api-key", apiKey);
var body = new StringContent(datasourceDefinition, Encoding.UTF8, "application/json");
request.Content = body;
return request;
}
static HttpRequestMessage PutIndexRequest(string searchServiceName, string apiKey, string indexName,
string indexDefinition)
{
var request = new HttpRequestMessage(HttpMethod.Put,
$"https://{searchServiceName}.search.windows.net/indexes/{indexName}?api-version=2016-09-01");
request.Headers.Add("api-key", apiKey);
var body = new StringContent(indexDefinition, Encoding.UTF8, "application/json");
request.Content = body;
return request;
}
static HttpRequestMessage PutIndexerRequest(string searchServiceName, string apiKey, string indexerName,
string indexerDefinition)
{
var request = new HttpRequestMessage(HttpMethod.Put,
$"https://{searchServiceName}.search.windows.net/indexers/{indexerName}?api-version=2016-09-01");
request.Headers.Add("api-key", apiKey);
var body = new StringContent(indexerDefinition, Encoding.UTF8, "application/json");
request.Content = body;
return request;
}
static HttpRequestMessage RunIndexerRequest(string searchServiceName, string apiKey, string indexerName)
{
var request = new HttpRequestMessage(HttpMethod.Post,
$"https://{searchServiceName}.search.windows.net/indexers/{indexerName}/run?api-version=2016-09-01");
request.Headers.Add("api-key", apiKey);
return request;
}
static string AzureSqlDatasourceDefinition(string connectionString, string tableName)
{
return @"
{
""description"": ""azure sql datasource"",
""type"": ""azuresql"",
""credentials"": { ""connectionString"": """ + connectionString + @""" },
""container"": { ""name"": """ + tableName + @""" },
""dataChangeDetectionPolicy"": {
""@odata.type"": ""#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy"",
""highWaterMarkColumnName"": ""highwatermark""
},
""dataDeletionDetectionPolicy"": {
""@odata.type"": ""#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy"",
""softDeleteColumnName"": ""deleted"",
""softDeleteMarkerValue"": ""true""
}
}
";
}
static string IndexDefinition()
{
return @"
{
""fields"": [
{
""name"": ""id"",
""type"": ""Edm.String"",
""key"": true,
""searchable"": true,
""sortable"": true,
""retrievable"": true
},
{
""name"": ""field1"",
""type"": ""Edm.String"",
""searchable"": true,
""retrievable"": true
},
{
""name"": ""field3"",
""type"": ""Edm.Int32"",
""retrievable"": true
}
]
}
";
}
static string IndexerDefinition(string dataSourceName, string indexName)
{
return @"
{
""description"": ""indexer for azure sql datasource"",
""dataSourceName"": """ + dataSourceName + @""",
""targetIndexName"": """ + indexName + @""",
""schedule"": { ""interval"": ""P1D"" }
}
";
}
}
The indexer is scheduled to run once per day. You can set it to run more frequently if the data changes often, but it might affect your search throughput.
This is the table definition if you're interested
CREATE TABLE [dbo].[testtable](
[id] [int] IDENTITY(1,1) NOT NULL,
[field1] [nchar](10) NULL,
[field2] [nchar](10) NULL,
[field3] [int] NULL,
[highwatermark] [timestamp] NOT NULL,
[deleted] [bit] NOT NULL
) ON [PRIMARY]
INSERT INTO [dbo].[testtable] (field1, field2, field3, deleted) VALUES ('abc', 'def', 123, 0)
回答2:
It looks like you're trying to modify your index definition, but the body of the request contains the api-key instead of the JSON for the index definition. The api-key needs to be in the request headers, not the body.
You might find it simpler to use the Azure Search .NET SDK instead of calling the REST API directly.
来源:https://stackoverflow.com/questions/47214406/azure-search-using-rest-c-sharp