Json.Netを使用しているとき、$ typeプロパティをレンダリングされたjsonに取得する方法を理解していますが、そのフィールド名を変更する方法はありますか?私は "$ type"の代わりに "__type"を使う必要があります。
答えて
これは、public const string TypePropertyName = "$type";
のNewtonsoft.Json.Serialization.JsonTypeReflector
にハードコードされていますが、内部の静的なクラスです。
私はこれを自分で必要としました。私が考えることができるのは、json.net自体のカスタム修正バージョンを持つことだけです。もちろん、これは大きなピタです。
残念ながら、私はかなり残念ながら私が完全に経路を断念しなければならなかったので、多くの場合、Json.Netがどれほど難しいかを使用することになります。これは単なる一例です。 –
私は自分自身がサーバー側でどのように私はC#で書かれ、Json.NETを使用して、ジャクソンを使用してAndroidアプリから送信されたJSONを非直列化できるかを見ています。ジャクソンでは "$ type"を使うように設定できますが、とにかく動作しません。 – Ted
http://json.codeplex.com/workitem/22429
"私はむしろ、ハードコード化され、一貫性のある$タイプを続けるだろう。"
私は不思議なものと一致しますか?
http://json.codeplex.com/workitem/21989
私はむしろないだろう - 私はこれが私にはあまりにも固有のものであり、私は の設定で船外に行きたくないと思います。ある時点で私はおそらく を実装しています - http://json.codeplex.com/workitem/21856 - 人がJSONのメタプロパティを読み書きできるようにして、 は新しいプロパティ名でタイプ名の処理を再実装することができます。 他のオプションは、自分自身のソースコードを変更して、そのプロパティ名が になるようにするだけです。
これは私がカスタムJsonReaderを作成したように、我々は、このための必要性を持っていた...
json.Replace("\"$type\": \"", "\"type\": \"");
あなたのソリューションは最高です!^_^ –
も参照してください:https://github.com/JamesNK/Newtonsoft.Json/issues/1331 – manuc66
私の解決策です。私たちは、複雑なデータモデルを持つMSのWebサービスでは安静を使用しており、 "__type"プロパティを "$ type"に置き換える必要がありました。
class MSJsonReader : JsonTextReader
{
public MSJsonTextReader(TextReader reader) : base(reader) { }
public override bool Read()
{
var hasToken = base.Read();
if (hasToken && base.TokenType == JsonToken.PropertyName && base.Value != null && base.Value.Equals("__type"))
base.SetToken(JsonToken.PropertyName, "$type");
return hasToken;
}
}
ここではどのように使用しますか。ここで
using(JsonReader jr = new MSJsonTextReader(sr))
{
JsonSerializer s = new JsonSerializer();
s.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
s.NullValueHandling = NullValueHandling.Ignore;
s.TypeNameHandling = TypeNameHandling.Auto; // Important!
s.Binder = new MSRestToJsonDotNetSerializationBinder("Server.DataModelsNamespace", "Client.GeneratedModelsNamespace");
T deserialized = s.Deserialize<T>(jr);
return deserialized;
}
はMS休息とJson.Net間の互換性を完了し、当社のMSRestToJsonDotNetSerializationBinderです。
class MSRestToJsonDotNetSerializationBinder : System.Runtime.Serialization.SerializationBinder
{
public string ServiceNamespace { get; set; }
public string LocalNamespace { get; set; }
public MSRestToJsonDotNetSerializationBinder(string serviceNamespace, string localNamespace)
{
if (serviceNamespace.EndsWith("."))
serviceNamespace = serviceNamespace.Substring(0, -1);
if(localNamespace.EndsWith("."))
localNamespace = localNamespace.Substring(0, -1);
ServiceNamespace = serviceNamespace;
LocalNamespace = localNamespace;
}
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
assemblyName = null;
typeName = string.Format("{0}:#{1}", serializedType.Name, ServiceNamespace); // MS format
}
public override Type BindToType(string assemblyName, string typeName)
{
string jsonDotNetType = string.Format("{0}.{1}", LocalNamespace, typeName.Substring(0, typeName.IndexOf(":#")));
return Type.GetType(jsonDotNetType);
}
}
カスタムタイプのプロパティ名をJson.NET
にシリアル化できる別のオプションがあります。アイデアはデフォルトの$type
プロパティを書きませんが、クラス自体のプロパティとして型名を導入します。
我々はLocation
クラスがあるとします、我々はtypeプロパティ名を導入し、以下に示すように、クラスを変更する
public class Location
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
まず必要があります。
public class Location
{
[JsonProperty("__type")]
public string EntityTypeName
{
get
{
var typeName = string.Format("{0}, {1}", GetType().FullName, GetType().Namespace);
return typeName;
}
}
public double Latitude { get; set; }
public double Longitude { get; set; }
}
その後、TypeNameHandling.None
にJsonSerializerSettings.TypeNameHandling
を設定デフォルトで$type
属性のレンダリングをスキップするためにデシリアライザを使用します。
これだけです。
例
var point = new Location() { Latitude = 51.5033630, Longitude = -0.1276250 };
var jsonLocation = JsonConvert.SerializeObject(point, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None, //do not write type property(!)
});
Console.WriteLine(jsonLocation);
結果
{"__type":"Namespace.Location, Namespace","Latitude":51.503363,"Longitude":-0.127625}
デシリアライズがソリューションで正しいタイプを決定する方法はわかりません。説明できますか? –
デシリアライズするには、 'JsonCreationConverter'を試してください。 http://stackoverflow.com/questions/8030538を参照してください。 – xmedeko
シリアライズするとき、プロパティ名オーバーライドする良い方法があります:
public class CustomJsonWriter : JsonTextWriter
{
public CustomJsonWriter(TextWriter writer) : base(writer)
{
}
public override void WritePropertyName(string name, bool escape)
{
if (name == "$type") name = "__type";
base.WritePropertyName(name, escape);
}
}
var serializer = new JsonSerializer();
var writer = new StreamWriter(stream) { AutoFlush = true };
serializer.Serialize(new CustomJsonWriter(writer), objectToSerialize);
私は試していないが、デシリアライゼーションはまだ、しかし、最悪の場合には私が使用することもできます
json.Replace("\"__type": \"", "\"type\": \"$type\");
Angular.js disregardsフィールド名は、ドル記号($)で始まるように私は私のUIのREST APIのためにこれをしなければなりませんでした。
そこでここでは、全体のWeb APIの__type
に$type
の名前を変更し、両方のシリアライズとデシリアライゼーションのために機能するソリューションです。の
internal class CustomJsonNetFormatter : JsonMediaTypeFormatter
{
public override JsonReader CreateJsonReader(Type type, Stream readStream, Encoding effectiveEncoding)
{
return new CustomJsonReader(readStream, effectiveEncoding);
}
public override JsonWriter CreateJsonWriter(Type type, Stream writeStream, Encoding effectiveEncoding)
{
return new CustomJsonWriter(writeStream, effectiveEncoding);
}
private class CustomJsonWriter : JsonTextWriter
{
public CustomJsonWriter(Stream writeStream, Encoding effectiveEncoding)
: base(new StreamWriter(writeStream, effectiveEncoding))
{
}
public override void WritePropertyName(string name, bool escape)
{
if (name == "$type") name = "__type";
base.WritePropertyName(name, escape);
}
}
private class CustomJsonReader : JsonTextReader
{
public CustomJsonReader(Stream readStream, Encoding effectiveEncoding)
: base(new StreamReader(readStream, effectiveEncoding))
{
}
public override bool Read()
{
var hasToken = base.Read();
if (hasToken && TokenType == JsonToken.PropertyName && Value != null && Value.Equals("__type"))
{
SetToken(JsonToken.PropertyName, "$type");
}
return hasToken;
}
}
}
:
カスタムJsonWriter
とカスタムJsonReader
を(この質問に対する他の回答で提案されている)を使用できるようにするために、我々はJsonMediaTypeFormatter
を継承し、対応するメソッドをオーバーライドする必要がありますもちろん、WebApiConfig
にカスタムフォーマッタを登録する必要があります。そこで、デフォルトのJson.NETフォーマッタをカスタムのものに置き換えます。
config.Formatters.Remove(config.Formatters.JsonFormatter);
config.Formatters.Add(new CustomJsonNetFormatter());
完了しました。
また、このようにそれを行うことができます:
[JsonConverter(typeof(JsonSubtypes), "ClassName")]
public class Annimal
{
public virtual string ClassName { get; }
public string Color { get; set; }
}
あなたはNewtonsoft.Json
プロジェクトの一部ではありませんJsonSubtypes
コンバータが必要になります。
- 1. Json.netの名前の変更プロパティ
- 2. Json.Netシリアル化中のプロパティの名前を変更します
- 3. Json.NETでFormatterAssemblyStyle.SimpleでType型のフィールドをシリアライズ
- 4. jazzhubで別名の名前を変更
- 5. Rの列の名前を位置別に変更します
- 6. Resharper名前を変更するフィールド
- 7. SubSonic selectステートメントのフィールドの名前を変更します。
- 8. circeでJSONフィールドの名前を変更
- 9. 名前フィールドの長さを変更します
- 10. 名前を変更してアイテムの名前を変更する
- 11. geokettleのフィールド名を変更します
- 12. ワードプレス:ボタンの名前を 'LOGOUT'からユーザーの名前に変更しますか?
- 13. いくつかのwoocommerceフィールドの名前を変更する
- 14. Laravel Migrationはnullableフィールドの回避策の名前を変更しますか?
- 15. ファイル名を変更して名前を変更しました
- 16. マングース変更弁別キーの名前
- 17. jqueryを使用してフィールド名の名前を変更できません
- 18. .netの名前空間の名前を変更します。
- 19. gffileの名前IDの名前を変更しています。
- 20. バッチファイルの名前を変更します。
- 21. アクセスクエリの名前を変更します。
- 22. Gsonはフィールド名で変数を持つが、別の名前の変数にフィールドを逆シリアル化する
- 23. Netsuiteで標準フィールドの名前を変更するには?
- 24. Azure SQL Serverの名前/名前を変更します。
- 25. awkはフィールド内のシンボルをカウントして名前を変更します
- 26. LaravelのクエリビルダwithCount(別名$ asColumn)から返されたフィールドの名前を変更する方法
- 27. Scalaから "type"という名前のJavaオブジェクトのフィールドにアクセスする方法
- 28. Select2は "text"キーの名前を別のものに変更できますか?
- 29. mysql:結合のすべてのフィールドの名前を変更します。
- 30. テーブルのフィールド値を持つSQLテーブルの列の名前を変更します。
[JSON-LD](http://json-ld.org)は '@ type'を使用しています –