我在 HttpClient 中使用 PostAsJsonAsync 來查詢 Elastic,它在第 12 行“通配符”上失敗了
我使用https://json2csharp.com/將示例 JSON 轉換為 C# 物件。
這是 Newtonsoft 生成的 json 失敗了。
{
"query": {
"bool": {
"must": [
{
"range": {
"@timestamp": {
"gte": "now-7d",
"lt": "now"
}
},
"wildcard": {
"request.keyword": {
"value": "/message/*/*-message/2c35669dd87e471faad1f90374d8d380/status",
"case_insensitive": true
}
}
}
]
}
}
}
這是我提供并用于將 json 轉換為 C# 物件的示例。
{
"query": {
"bool": {
"must": [
{
"range": {
"@timestamp": {
"gte": "now-7d",
"lt": "now"
}
}
},
{
"wildcard": {
"request.keyword": {
"value": "/message/*/*-message/2c35669dd87e471faad1f90374d8d380/status",
"case_insensitive": true
}
}
}
]
}
}
}
兩者都是有效的 JSON,但 Elastic 只接受第二個。它似乎期望在必須的屬性周圍有花括號,但我不知道如何讓 JSON 以這種方式序列化。
uj5u.com熱心網友回復:
您遇到了https://json2csharp.com/等代碼生成工具的限制,即它們不能很好地處理隱含的多型性。在這種情況下,您可能需要手動修復生成的類。
考慮以下包含兩種不同型別物件的 JSON 陣列:
[{"A" : "a value"},{"B" : "b value"}]
該陣列包含具有 propertyA或 property的物件B,但如果您從此 JSON 生成類,您將獲得具有兩個屬性的單一合并型別:
public class Root
{
public string A { get; set; }
public string B { get; set; }
}
而您真正想要的是:
public interface IRootBase { }
public class A : IRootBase
{
public string A { get; set; }
}
public class B : IRootBase
{
public string B { get; set; }
}
給定這樣的模型,您將能夠構造 aList<IRootBase>并將其序列化以獲取顯示的 JSON。(并且,要反序列化,請參閱使用 json.net 反序列化沒有型別資訊的多型 json 類。)
在您的情況下,問題出在 的陣列值上"must"。如您所見,此陣列包含兩種不同型別的物件:
[
{
"range":{
"@timestamp":{
"gte":"now-7d",
"lt":"now"
}
}
},
{
"wildcard":{
"request.keyword":{
"value":"/message/*/*-message/2c35669dd87e471faad1f90374d8d380/status",
"case_insensitive":true
}
}
}
]
但是https://json2csharp.com/將創建以下組合型別:
public class Must
{
public Range range { get; set; }
public Wildcard wildcard { get; set; }
}
如果您要創建一個包含兩個屬性的單個實體的陣列Must,您會得到 Elastic 拒絕的無效 JSON。
相反,您需要手動修改自動生成的型別,如下所示:
#region Manually created from Must
public interface IMustConstraint { }
public class RangeConstraint : IMustConstraint
{
public Range range { get; set; }
}
public class WildcardConstraint : IMustConstraint
{
public Wildcard wildcard { get; set; }
}
#endregion Manually created from Must
public class Range
{
[JsonProperty("@timestamp")]
public Timestamp Timestamp { get; set; }
}
public class Timestamp
{
public string gte { get; set; }
public string lt { get; set; }
}
public class Wildcard
{
[JsonProperty("request.keyword")]
public RequestKeyword RequestKeyword { get; set; }
}
public class RequestKeyword
{
public string value { get; set; }
public bool case_insensitive { get; set; }
}
public class BoolQuery // Renamed from Bool for clarity
{
public List<IMustConstraint> must { get; set; } // Modified from List<Must>
}
public class Query
{
public BoolQuery @bool { get; set; }
}
public class Root
{
public Query query { get; set; }
}
現在您將能夠:
Root root = new ()
{
query = new ()
{
@bool = new ()
{
must = new ()
{
new RangeConstraint() { range = new () { Timestamp = new () { gte = "now-7d", lt = "now" } } },
new WildcardConstraint() { wildcard = new () { RequestKeyword = new () { value = "/message/*/*-message/2c35669dd87e471faad1f90374d8d380/status", case_insensitive = true } } },
},
},
},
};
var json = JsonConvert.SerializeObject(root, Formatting.Indented);
并創建您所需的 JSON。
演示小提琴在這里。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/489611.html
