2013-12-16 23 views
9

私はいくつかのDTOを直列化するためにJson.Netを使用しているASP.Net MVCを使用していくつかのC#コードを持っています。ペイロードを減らすために、[JsonProperty(PropertyName = "shortName")]属性を使用して、直列化中に短いプロパティ名を使用しました。jsonをシリアライズするときにJsonProperty(PropertyName = "someName")を無視する方法は?

これは、実際の転送ペイロードを低く保ちながら、デシリアライゼーションがオブジェクト階層を一緒に戻すので、クライアントが別の.Netアプリケーションまたはサービスである場合に効果的です。

この問題は、クライアントがブラウザ経由でjavascript/ajaxを使用している場合に発生します。要求を出してjsonを取得します...しかし、そのjsonは短縮された使いにくい名前を使用しています。

json.netシリアル化エンジンで[JsonProperty(PropertyName = "shortName")]属性をプログラムで無視させる方法を教えてください。理想的には、私のMVCサービスは実行中に座り、短縮されたプロパティ名を使って通常はシリアル化されます。私のコードが特定のパラメータを検出すると、長い名前を使用してデータをシリアル化し、[JsonProperty()]属性を無視したいと思います。

提案がありますか?

おかげで、

ケビン

+0

ちょうど 'JsonProperty'を削除し、応じて匿名オブジェクトを返します渡されたパラメータに渡します。 'new {UserName = uname} 'のようなもの –

+0

私は最良の方法は、(json.NETを使って、最初からではなく)カスタムシリアライザを作成し、アノテーションを削除することだと思います。短い名前と長い名前をシリアライザの設定にして、シリアライザの時に必要なものを伝えるだけです。 json.NETは、実行時にアノテーションを使用/無視する機能をサポートしていません。彼らがコンパイル時にそこにいるなら、それらは使用されます(いくつかの主要なハッキングを禁止します)。 – evanmcdonnal

+0

コメントをいただきありがとうございます。 @evanmcdonnal:カスタムシリアライザを使用した場合、DTO固有のレベル(すべてのDTOに添付されていますか?)でこれを行う必要がありますか?多くの開発チームを通じて多くのDTOが多数のソリューションに広がっています。理想的には、シリアル化プロセスに取り付ける比較的洗練された方法を見つけることができます。 – Kevin

答えて

23

これは、カスタム契約リゾルバを使用してかなり簡単に行うことができます。ここでは、必要となるすべてのコードです:

class LongNameContractResolver : DefaultContractResolver 
{ 
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
    { 
     // Let the base class create all the JsonProperties 
     // using the short names 
     IList<JsonProperty> list = base.CreateProperties(type, memberSerialization); 

     // Now inspect each property and replace the 
     // short name with the real property name 
     foreach (JsonProperty prop in list) 
     { 
      prop.PropertyName = prop.UnderlyingName; 
     } 

     return list; 
    } 
} 

はここリゾルバを使用してクイックデモです:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Foo foo = new Foo 
     { 
      CustomerName = "Bubba Gump Shrimp Company", 
      CustomerNumber = "BG60938" 
     }; 

     Console.WriteLine("--- Using JsonProperty names ---"); 
     Console.WriteLine(Serialize(foo, false)); 
     Console.WriteLine(); 
     Console.WriteLine("--- Ignoring JsonProperty names ---"); 
     Console.WriteLine(Serialize(foo, true)); 
    } 

    static string Serialize(object obj, bool useLongNames) 
    { 
     JsonSerializerSettings settings = new JsonSerializerSettings(); 
     settings.Formatting = Formatting.Indented; 
     if (useLongNames) 
     { 
      settings.ContractResolver = new LongNameContractResolver(); 
     } 

     return JsonConvert.SerializeObject(obj, settings); 
    } 
} 

class Foo 
{ 
    [JsonProperty("cust-num")] 
    public string CustomerNumber { get; set; } 
    [JsonProperty("cust-name")] 
    public string CustomerName { get; set; } 
} 

は出力:

--- Using JsonProperty names --- 
{ 
    "cust-num": "BG60938", 
    "cust-name": "Bubba Gump Shrimp Company" 
} 

--- Ignoring JsonProperty names --- 
{ 
    "CustomerNumber": "BG60938", 
    "CustomerName": "Bubba Gump Shrimp Company" 
} 
関連する問題