我正在使用Microsoft.Azure.Search版本3.0.1,
我正在尝试以下方法:
// subset of my index's fields
private class SyncFields
{
public string Id { get; set; }
public DateTimeOffset? ApprovedOn { get; set; }
public DateTimeOffset? IgnoredOn { get; set; }
}
public void Sync()
{
var sync = new SyncFields
{
Id = "94303",
ApprovedOn = null,
IgnoredOn = DateTime.UtcNow
};
var searchClient = new SearchServiceClient("xxxx",
new SearchCredentials("xxxx"));
searchClient.SerializationSettings.NullValueHandling = NullValueHandling.Include;
using (var client = searchClient.Indexes.GetClient("xxxx"))
{
client.SerializationSettings.NullValueHandling = NullValueHandling.Include;
var batch = IndexBatch.Merge<SyncFields>(new[] { sync });
client.Documents.Index<SyncFields>(batch);
}
}
这不是将ApprovedOn
设置为null。它忽略了它。如果我设置了一个非空值,它会设置它。
根据文档here,合并操作将字段更新为null。事实上,如果我用JSON手动发出这个Http post请求,这是真的。但SDK没有将字段更新为null。我错过了什么?
答案 0 :(得分:2)
我找到了the culprit in the Azure Search SDK source。
第51行,settings.NullValueHandling = NullValueHandling.Ignore;
覆盖了我尝试设置的设置。我可能会在Github上提出这个问题。
目前,我正在使用自定义转换器作为解决方法。
public class DefaultDateTimeOffsetIsNullConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(DateTimeOffset?));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var date = (DateTimeOffset?)value;
if (date == default(DateTimeOffset))
{
writer.WriteNull();
}
else
{
writer.WriteValue(date);
}
}
public override bool CanRead => false;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
在
中var sync = new SyncFields
{
Id = "94303",
ApprovedOn = default(DateTimeOffset), // set to null
IgnoredOn = DateTime.UtcNow
};
// ...
client.SerializationSettings.Converters.Add(new DefaultDateTimeOffsetIsNullConverter());
// ...
修改强>
Bruce列出的另外两个优先选项:使用无类型的Document,并使用字段上的JsonPropertyAttribute来获得正确的序列化。使用Document非常适合我的用例,没有序列化问题或自定义转换器:
var sync = new Document
{
["Id"] = "94303",
["ApprovedOn"] = null,
["IgnoredOn"] = null
};
// ... the same as before:
var batch = IndexBatch.Merge(new[] { sync });
await client.Documents.IndexAsync(batch);
答案 1 :(得分:2)
这是Index
系列方法的类型重载的已知限制。此处详细介绍了此问题:https://github.com/Azure/azure-sdk-for-net/issues/1804
一些解决方法:
Index
代替合并方案。Upload
代替Merge
。[JsonProperty(NullValueHandling = NullValueHandling.Include)]
放在模型类的属性上,您需要在合并操作中显式设置为null(如果索引中有许多字段,不推荐)。