当尝试使用 Azuren 搜索和 Azure Table 存储覆盖分区键时,.NET 收到错误请求
When trying to override Partition Key using Azuren Search and Azure Table Storage with .NET getting bad request
我正在使用 Azuren Search 和 Azure Table Storage 以及 .net,我正在尝试索引一个 table 并使分区键现在可以过滤,这在我尝试插入一些东西之前工作正常在那个 table 中,我收到一个没有太多附加信息的 BadRequest。
这是我的 class 波纹管
using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Microsoft.WindowsAzure.Storage.Table;
[SerializePropertyNamesAsCamelCase]
public class Asset : TableEntity
{
public Asset(string name)
{
Name = name;
}
public Asset()
{
}
public Asset(string name, DateTimeOffset toBePublished, string pkey)
{
Name = name;
ToBePublishedDate = toBePublished;
PartitionKey = pkey;
}
[System.ComponentModel.DataAnnotations.Key]
public string Id { get; set; } = DateTimeOffset.UtcNow.ToString("O")
.Replace("+", string.Empty)
.Replace(":", string.Empty)
.Replace(".", string.Empty);
[IsFilterable, IsSortable, IsSearchable]
public new string PartitionKey { get; set; }
[IsFilterable, IsSortable, IsSearchable]
public string Name { get; set; } = "TemptAsset " + new Guid();
[IsFilterable, IsSortable]
public int? Version { get; set; } = 1;
[IsFilterable, IsSortable]
public DateTimeOffset? ToBePublishedDate { get; set; } = DateTimeOffset.UtcNow;
[IsFilterable, IsSortable]
public DateTimeOffset? ToBeRetiredDate { get; set; } = null;
[IsFilterable, IsSearchable, IsSortable]
public string Company { get; set; } = "TempCompany";
[IsFilterable, IsSortable]
public bool IsApproved { get; set; } = false;
[IsFilterable, IsSortable]
public bool IsDraft { get; set; } = true;
}
这 运行s 并且索引创建成功见下文
现在,如果我尝试向该 table 添加一个实体,我会得到一个 BadRequest,但是通过在我的实体中注释掉 PartitionKey 来做完全相同的事情,这工作正常。
这就是我创建索引的方式
AzureSearch.CreateAssetNameIndex(AzureSearch.CreateSearchServiceClient());
and the methods called bellow
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AssetSynch.Models;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
public static SearchServiceClient CreateSearchServiceClient()
{
string searchServiceName = "*****";
string adminApiKey = "********";
SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName,
new SearchCredentials(adminApiKey));
return serviceClient;
}
public static async void CreateAssetNameIndex(SearchServiceClient serviceClient)
{
Index definition = new Index
{
Name = "assetname",
Fields = FieldBuilder.BuildForType<Asset>()
};
await serviceClient.Indexes.CreateAsync(definition);
}
如果我 return 使用邮递员时出现错误,这是我得到的异常
{
"innerExceptions": [
{
"requestInformation": {
"httpStatusCode": 400,
"httpStatusMessage": "Bad Request",
"serviceRequestID": "59efbc9a-0002-002c-3570-d5d55c000000",
"contentMd5": null,
"etag": null,
"requestDate": "Thu, 25 May 2017 17:05:01 GMT",
"targetLocation": 0,
"extendedErrorInformation": {
"errorCode": "PropertiesNeedValue",
"errorMessage": "The values are not specified for all properties in the entity.\nRequestId:59efbc9a-0002-002c-3570-d5d55c000000\nTime:2017-05-25T16:05:06.5197909Z",
"additionalDetails": {}
},
"isRequestServerEncrypted": false
}
}
]
}
如果我从我的实体中删除分区键并重新 运行 相同的代码以重新创建索引,则相同的代码段将成功执行。
我注意到的是,我的实体上现在有 2 个分区键,其中一个将保持为空,请参见下图,并且我的 属性 不会覆盖原始的。
这里有什么我遗漏的吗?
根据你的代码,我发现你的资产使用了new关键字来修改基础class的分区属性。
但这只会隐藏 base.partition 而不会覆盖它。
public new string PartitionKey { get; set; }
在Asset class中设置值后,您会发现它包含如下两个分区:
所以如果基class的分区键值为空,就会return 400错误。
因此,如果您想将新实体添加到 table,您需要设置基础 class(TableEntity) 分区键值。
所以我建议您可以如下更改您的资产:
[SerializePropertyNamesAsCamelCase]
public class Asset : TableEntity
{
public Asset(string name)
{
Name = name;
base.PartitionKey = this.PartitionKey;
}
public Asset()
{
base.PartitionKey = this.PartitionKey;
}
public Asset(string name, DateTimeOffset toBePublished, string pkey)
{
Name = name;
ToBePublishedDate = toBePublished;
PartitionKey = pkey;
base.PartitionKey = this.PartitionKey;
}
[Key]
[IsFilterable]
public string Id { get; set; } = DateTimeOffset.UtcNow.ToString("O")
.Replace("+", string.Empty)
.Replace(":", string.Empty)
.Replace(".", string.Empty);
[IsFilterable, IsSortable, IsSearchable]
public new string PartitionKey { get; set; }
[IsFilterable, IsSortable, IsSearchable]
public string Name { get; set; } = "TemptAsset " + new Guid();
[IsFilterable, IsSortable]
public int? Version { get; set; } = 1;
[IsFilterable, IsSortable]
public DateTimeOffset? ToBePublishedDate { get; set; } = DateTimeOffset.UtcNow;
[IsFilterable, IsSortable]
public DateTimeOffset? ToBeRetiredDate { get; set; } = null;
[IsFilterable, IsSearchable, IsSortable]
public string Company { get; set; } = "TempCompany";
[IsFilterable, IsSortable]
public bool IsApproved { get; set; } = false;
[IsFilterable, IsSortable]
public bool IsDraft { get; set; } = true;
}
如果你想使用table存储作为数据源,我建议你可以参考这个article。
我正在使用 Azuren Search 和 Azure Table Storage 以及 .net,我正在尝试索引一个 table 并使分区键现在可以过滤,这在我尝试插入一些东西之前工作正常在那个 table 中,我收到一个没有太多附加信息的 BadRequest。 这是我的 class 波纹管
using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Microsoft.WindowsAzure.Storage.Table;
[SerializePropertyNamesAsCamelCase]
public class Asset : TableEntity
{
public Asset(string name)
{
Name = name;
}
public Asset()
{
}
public Asset(string name, DateTimeOffset toBePublished, string pkey)
{
Name = name;
ToBePublishedDate = toBePublished;
PartitionKey = pkey;
}
[System.ComponentModel.DataAnnotations.Key]
public string Id { get; set; } = DateTimeOffset.UtcNow.ToString("O")
.Replace("+", string.Empty)
.Replace(":", string.Empty)
.Replace(".", string.Empty);
[IsFilterable, IsSortable, IsSearchable]
public new string PartitionKey { get; set; }
[IsFilterable, IsSortable, IsSearchable]
public string Name { get; set; } = "TemptAsset " + new Guid();
[IsFilterable, IsSortable]
public int? Version { get; set; } = 1;
[IsFilterable, IsSortable]
public DateTimeOffset? ToBePublishedDate { get; set; } = DateTimeOffset.UtcNow;
[IsFilterable, IsSortable]
public DateTimeOffset? ToBeRetiredDate { get; set; } = null;
[IsFilterable, IsSearchable, IsSortable]
public string Company { get; set; } = "TempCompany";
[IsFilterable, IsSortable]
public bool IsApproved { get; set; } = false;
[IsFilterable, IsSortable]
public bool IsDraft { get; set; } = true;
}
这 运行s 并且索引创建成功见下文
现在,如果我尝试向该 table 添加一个实体,我会得到一个 BadRequest,但是通过在我的实体中注释掉 PartitionKey 来做完全相同的事情,这工作正常。 这就是我创建索引的方式
AzureSearch.CreateAssetNameIndex(AzureSearch.CreateSearchServiceClient());
and the methods called bellow
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AssetSynch.Models;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
public static SearchServiceClient CreateSearchServiceClient()
{
string searchServiceName = "*****";
string adminApiKey = "********";
SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName,
new SearchCredentials(adminApiKey));
return serviceClient;
}
public static async void CreateAssetNameIndex(SearchServiceClient serviceClient)
{
Index definition = new Index
{
Name = "assetname",
Fields = FieldBuilder.BuildForType<Asset>()
};
await serviceClient.Indexes.CreateAsync(definition);
}
如果我 return 使用邮递员时出现错误,这是我得到的异常
{
"innerExceptions": [
{
"requestInformation": {
"httpStatusCode": 400,
"httpStatusMessage": "Bad Request",
"serviceRequestID": "59efbc9a-0002-002c-3570-d5d55c000000",
"contentMd5": null,
"etag": null,
"requestDate": "Thu, 25 May 2017 17:05:01 GMT",
"targetLocation": 0,
"extendedErrorInformation": {
"errorCode": "PropertiesNeedValue",
"errorMessage": "The values are not specified for all properties in the entity.\nRequestId:59efbc9a-0002-002c-3570-d5d55c000000\nTime:2017-05-25T16:05:06.5197909Z",
"additionalDetails": {}
},
"isRequestServerEncrypted": false
}
}
]
}
如果我从我的实体中删除分区键并重新 运行 相同的代码以重新创建索引,则相同的代码段将成功执行。 我注意到的是,我的实体上现在有 2 个分区键,其中一个将保持为空,请参见下图,并且我的 属性 不会覆盖原始的。
这里有什么我遗漏的吗?
根据你的代码,我发现你的资产使用了new关键字来修改基础class的分区属性。
但这只会隐藏 base.partition 而不会覆盖它。
public new string PartitionKey { get; set; }
在Asset class中设置值后,您会发现它包含如下两个分区:
所以如果基class的分区键值为空,就会return 400错误。
因此,如果您想将新实体添加到 table,您需要设置基础 class(TableEntity) 分区键值。
所以我建议您可以如下更改您的资产:
[SerializePropertyNamesAsCamelCase]
public class Asset : TableEntity
{
public Asset(string name)
{
Name = name;
base.PartitionKey = this.PartitionKey;
}
public Asset()
{
base.PartitionKey = this.PartitionKey;
}
public Asset(string name, DateTimeOffset toBePublished, string pkey)
{
Name = name;
ToBePublishedDate = toBePublished;
PartitionKey = pkey;
base.PartitionKey = this.PartitionKey;
}
[Key]
[IsFilterable]
public string Id { get; set; } = DateTimeOffset.UtcNow.ToString("O")
.Replace("+", string.Empty)
.Replace(":", string.Empty)
.Replace(".", string.Empty);
[IsFilterable, IsSortable, IsSearchable]
public new string PartitionKey { get; set; }
[IsFilterable, IsSortable, IsSearchable]
public string Name { get; set; } = "TemptAsset " + new Guid();
[IsFilterable, IsSortable]
public int? Version { get; set; } = 1;
[IsFilterable, IsSortable]
public DateTimeOffset? ToBePublishedDate { get; set; } = DateTimeOffset.UtcNow;
[IsFilterable, IsSortable]
public DateTimeOffset? ToBeRetiredDate { get; set; } = null;
[IsFilterable, IsSearchable, IsSortable]
public string Company { get; set; } = "TempCompany";
[IsFilterable, IsSortable]
public bool IsApproved { get; set; } = false;
[IsFilterable, IsSortable]
public bool IsDraft { get; set; } = true;
}
如果你想使用table存储作为数据源,我建议你可以参考这个article。