誰かが重複としてマークしたが、そうではないのでこの質問を再掲載しています。可変内容のC#を使用してJsonをデシリアライズ
Webアプリケーションがデータを取得するためのAPIをC#で作成しています。私のWebアプリケーションでは、私は製品のリストを持つビューを持っています。今のところ、私はデータベースに格納されているすべての私の製品を返すルートを持っています。
ここで、Webアプリケーションが複合フィルタを作成する機能を追加したいと思います。 webappや、郵便配達員と一緒に、私のルートに到達することができるようにしたいと考えています(「let's say)/ api/product」には、webappが適用する必要があるすべてのフィルタを含む "filters"という名前のURlParamがあります。
私のWebAppに戻ってください(角度をつけてビルド)フィルタのツリーのように作成できるサービスがあります(下記のクラスアーキテクチャを参照してください)。 (そして、そう、このアーキテクチャを向上させることができる)
アイデアは、私はこのようなフィルタを構築することができるということです。私は自分の名前に「foo」を持っているすべての製品を取得したい場合や価格gretterと比べて15 $:
let filter = new AndNode();
filter.Add(new LikeNode("name", "foo"));
filter.Add(new GTNode("price", 15));
filter.generateJson();
は、このJSONになります:
{
"$and": [
{
"$like": { "key": "name", "value": "foo" }
},
{
"$gt": { "key": "price", "value": 15 }
}
]
}
は今、このJSONは1つの要件を持っている:それは、複数のPRを含んでいてはいけませんオペラは一階です。これはSQLフィルタを生成するために使用されるため、jsonには最初のレベルに1つのノード、EQ、LIKE、GT、またはLTノードが含まれている必要があります。/ORノードは、次のレベルの各フィルタ間の論理「接続」を定義する。
だから、という意味があります:
{
"$like": { "key": "name", "value": "foo" }
}
が有効であり、このSQL文につながる可能性:
SELECT * FROM products WHERE name LIKE "%foo%";
また:
{
"$and": [
{
"$like": { "key": "name", "value": "foo" }
},
{
"$gt": { "key": "price", "value": 15 }
}
]
}
は有効であり、このようつながる可能性SQLステートメント:
SELECT * FROM products WHERE name LIKE "%foo%" AND price > 15;
しかし:
SELECT * FROM products WHERE name LIKE "%foo%" price > 15
魔女が見つからないため、ANDやORキーワードで有効ではありません:それは、このSQL文を発生しますので、
{
"$like": { "key": "name", "value": "foo" },
"$eq": { "key": "price", "value": 5 },
}
は有効ではありません。
私がしたいこと: 美しい世界では、このjsonをWebアプリケーションでシリアル化し、有効なURLパラメータ文字列に変換してAPI(c#)に送信したいと思います。 JSONをデシリアライズして、WebApp上で同じオブジェクト構造を取得します。 価格と名前の例では、LikeNodeクラスのインスタンスとGTNodeクラスのインスタンスの2つのオブジェクトを含むメンバー "child"を持つAndNodeクラスのインスタンスを持っています。
この実装は議論の余地があるかもしれませんが、今のところこれが必要です。今の
は、私が持っている:
public class EQNode
{
[JsonProperty("key")]
public string key { get; set; }
[JsonProperty("value")]
public int value { get; set; }
}
public class LikeNode
{
[JsonProperty("key")]
public string key { get; set; }
[JsonProperty("value")]
public string value { get; set; }
}
public class GTNode
{
[JsonProperty("key")]
public string key { get; set; }
[JsonProperty("value")]
public int value { get; set; }
}
public class LTNode
{
[JsonProperty("key")]
public string key { get; set; }
[JsonProperty("value")]
public int value { get; set; }
}
public class OrNode
{
[JsonProperty("$eq")]
public EQNode eq { get; set; }
}
public class AndNode
{
[JsonProperty("$eq")]
public EQNode eq { get; set; }
[JsonProperty("$like")]
public LikeNode like { get; set; }
[JsonProperty("$gt")]
public GTNode gt { get; set; }
[JsonProperty("$lt")]
public LTNode lt { get; set; }
[JsonProperty("$or")]
public List<OrNode> or { get; set; }
[JsonProperty("$and")]
public List<OrNode> and { get; set; }
}
public class RootObject
{
[JsonProperty("$and")]
public List<AndNode> and { get; set; }
[JsonProperty("$or")]
public List<OrNode> or { get; set; }
[JsonProperty("$eq")]
public EQNode eq { get; set; }
[JsonProperty("$like")]
public LikeNode like { get; set; }
[JsonProperty("$gt")]
public GTNode gt { get; set; }
[JsonProperty("$lt")]
public LTNode lt { get; set; }
}
これは、Visual Studioの「過去の特別な」機能によって生成された(と私は、JSON内の名前と一致するように、すべてのJsonPropertyデコレータを追加しました)。 それは動作しますが、これは私が期待したものではありません。
まず、WebApp構造から最も近い構造を継承したいと考えています。 第二に、私は、この生成されたコードが私のルートオブジェクトに$ eq、$ gt、$ lt、$ like、$ orまたは$ and nodeを持つことができるという事実を処理する方法が嫌い、そのようなきれいな構造を持っている方法はありません: (注:これは、これは単なるデモ用で、例えば、目的のために使用されるいくつかのデコレータが存在しない場合、またはひどく使用されている)
public class RootObject {
public FilterNode root;
}
public class FilterNode {
}
public class ConjunctionNode: FilterNode {
public FilterNode[] childs
}
[JsonObject("$and")]
public class AndNode: ConjunctionNode {
}
[JsonObject("$or")]
public class OrNode: ConjunctionNode {
}
[JsonObject("$like")]
public class LikeNode: FilterNode {
public string key;
public string value;
}
[JsonObject("$eq")]
public class EQNode: FilterNode {
public string key;
public string value;
}
[JsonObject("$gt")]
public class GTNode: FilterNode {
public string key;
public string value;
}
[JsonObject("$lt")]
public class LTNode: FilterNode {
public string key;
public string value;
}
だから、私たちが使用している場合サンプルJSON:私は使用することができ
{
"$and": [
{
"$like": { "key": "name", "value": "foo" }
},
{
"$gt": { "key": "price", "value": 15 }
}
]
}
:
RootObject obj = JsonConvert.DeserializeObject<RootObject>(filters);
RootObjectの "root"メンバーをAndNodeのインスタンスとして使用します。 このAndNodeには、この子の配列にあるLikeNodeのインスタンスとGTNodeのインスタンスの2つのオブジェクトが含まれます。
これはできますか?
最初の質問に回答がありますか? – Izzy
私の元の投稿はそれほど詳細ではありませんでした。しかし、そこには次のような反応があります。「過去の特別な機能」を使うことは良いアドバイスであり、他の答えは私に詳細を求めていました。今のところ私はこれを解決するために答えました。 –
新しい質問を投稿するのではなく、最初の質問を更新する必要があります。また、@ angsuman-rayは詳細なJSONを要求し、その外観からは戻っていません。 – Izzy