diff --git a/src/idl_gen_csharp.cpp b/src/idl_gen_csharp.cpp
index bfa5992b1..5e7ca1db1 100644
--- a/src/idl_gen_csharp.cpp
+++ b/src/idl_gen_csharp.cpp
@@ -147,6 +147,21 @@ class CSharpGenerator : public BaseGenerator {
std::string one_file_code;
cur_name_space_ = parser_.current_namespace_;
+ if (parser_.opts.cs_gen_json_serializer &&
+ parser_.opts.generate_object_based_api) {
+ std::string contractresolvercode;
+ GenJsonContractResolver(&contractresolvercode);
+
+ if (parser_.opts.one_file) {
+ one_file_code += contractresolvercode;
+ } else {
+ if (!SaveType("JsonContractResolver", *parser_.current_namespace_,
+ contractresolvercode, true, parser_.opts)) {
+ return false;
+ }
+ }
+ }
+
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) {
std::string enumcode;
@@ -2395,6 +2410,9 @@ class CSharpGenerator : public BaseGenerator {
auto utype_name = NamespacedName(*field.value.type.enum_def);
code +=
" [Newtonsoft.Json.JsonProperty(\"" + field.name + "_type\")]\n";
+ if (field.deprecated == FieldDef::kDeprecatedReadOnly) {
+ code += " [JsonReadOnly()]\n";
+ }
if (IsVector(field.value.type)) {
code += " private " + utype_name + "[] " + camel_name + "Type {\n";
code += " get {\n";
@@ -2442,6 +2460,8 @@ class CSharpGenerator : public BaseGenerator {
}
if (field.attributes.Lookup("hash")) {
code += " [Newtonsoft.Json.JsonIgnore()]\n";
+ } else if (field.deprecated == FieldDef::kDeprecatedReadOnly) {
+ code += " [JsonReadOnly()]\n";
}
}
code += " public " + type_name + " " + camel_name + " { get; set; }\n";
@@ -2491,12 +2511,18 @@ class CSharpGenerator : public BaseGenerator {
code += " public static " + class_name +
" DeserializeFromJson(string jsonText) {\n";
code += " return Newtonsoft.Json.JsonConvert.DeserializeObject<" +
- class_name + ">(jsonText);\n";
+ class_name +
+ ">(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {\n";
+ code += " ContractResolver = new JsonContractResolver(),\n";
+ code += " });\n";
code += " }\n";
code += " public string SerializeToJson() {\n";
code +=
- " return Newtonsoft.Json.JsonConvert.SerializeObject(this, "
- "Newtonsoft.Json.Formatting.Indented);\n";
+ " return Newtonsoft.Json.JsonConvert.SerializeObject(this, new "
+ "Newtonsoft.Json.JsonSerializerSettings() {\n";
+ code += " ContractResolver = new JsonContractResolver(),\n";
+ code += " Formatting = Newtonsoft.Json.Formatting.Indented,\n";
+ code += " });\n";
code += " }\n";
}
if (parser_.root_struct_def_ == &struct_def) {
@@ -2515,6 +2541,35 @@ class CSharpGenerator : public BaseGenerator {
code += "}\n\n";
}
+ void GenJsonContractResolver(std::string *code_ptr) const {
+ auto &code = *code_ptr;
+ code +=
+ "[AttributeUsage(AttributeTargets.Property | "
+ "AttributeTargets.Field)]\n";
+ code += "class JsonReadOnlyAttribute : Attribute {\n";
+ code += "}\n\n";
+
+ code +=
+ "public class JsonContractResolver : "
+ "Newtonsoft.Json.Serialization.DefaultContractResolver\n";
+ code += "{\n";
+ code +=
+ " protected override Newtonsoft.Json.Serialization.JsonProperty "
+ "CreateProperty(System.Reflection.MemberInfo member, "
+ "Newtonsoft.Json.MemberSerialization memberSerialization)\n";
+ code += " {\n";
+ code +=
+ " var property = base.CreateProperty(member, "
+ "memberSerialization);\n";
+ code +=
+ " if (Attribute.IsDefined(member, "
+ "typeof(JsonReadOnlyAttribute)))\n";
+ code += " property.Readable = false;\n";
+ code += " return property;\n";
+ code += " }\n";
+ code += "}\n\n";
+ }
+
// This tracks the current namespace used to determine if a type need to be
// prefixed by its namespace
const Namespace *cur_name_space_;
diff --git a/tests/KeywordTest/JsonContractResolver.cs b/tests/KeywordTest/JsonContractResolver.cs
new file mode 100644
index 000000000..e94a516cf
--- /dev/null
+++ b/tests/KeywordTest/JsonContractResolver.cs
@@ -0,0 +1,28 @@
+//
+// automatically generated by the FlatBuffers compiler, do not modify
+//
+
+namespace KeywordTest
+{
+
+using global::System;
+using global::System.Collections.Generic;
+using global::Google.FlatBuffers;
+
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
+
+}
diff --git a/tests/MyGame/Example/ArrayTable.cs b/tests/MyGame/Example/ArrayTable.cs
index d688e401e..9daabaee6 100644
--- a/tests/MyGame/Example/ArrayTable.cs
+++ b/tests/MyGame/Example/ArrayTable.cs
@@ -57,10 +57,15 @@ public class ArrayTableT
}
public static ArrayTableT DeserializeFromJson(string jsonText) {
- return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText);
+ return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ });
}
public string SerializeToJson() {
- return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ Formatting = Newtonsoft.Json.Formatting.Indented,
+ });
}
public static ArrayTableT DeserializeFromBinary(byte[] fbBuffer) {
return ArrayTable.GetRootAsArrayTable(new ByteBuffer(fbBuffer)).UnPack();
diff --git a/tests/MyGame/Example/JsonContractResolver.cs b/tests/MyGame/Example/JsonContractResolver.cs
new file mode 100644
index 000000000..ebf716c7f
--- /dev/null
+++ b/tests/MyGame/Example/JsonContractResolver.cs
@@ -0,0 +1,28 @@
+//
+// automatically generated by the FlatBuffers compiler, do not modify
+//
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::System.Collections.Generic;
+using global::Google.FlatBuffers;
+
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
+
+}
diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs
index fb4c9e744..a8e6752d4 100644
--- a/tests/MyGame/Example/Monster.cs
+++ b/tests/MyGame/Example/Monster.cs
@@ -1085,10 +1085,15 @@ public class MonsterT
}
public static MonsterT DeserializeFromJson(string jsonText) {
- return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText);
+ return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ });
}
public string SerializeToJson() {
- return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ Formatting = Newtonsoft.Json.Formatting.Indented,
+ });
}
public static MonsterT DeserializeFromBinary(byte[] fbBuffer) {
return Monster.GetRootAsMonster(new ByteBuffer(fbBuffer)).UnPack();
diff --git a/tests/MyGame/JsonContractResolver.cs b/tests/MyGame/JsonContractResolver.cs
new file mode 100644
index 000000000..099573ce8
--- /dev/null
+++ b/tests/MyGame/JsonContractResolver.cs
@@ -0,0 +1,28 @@
+//
+// automatically generated by the FlatBuffers compiler, do not modify
+//
+
+namespace MyGame
+{
+
+using global::System;
+using global::System.Collections.Generic;
+using global::Google.FlatBuffers;
+
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
+
+}
diff --git a/tests/MyGame/MonsterExtra.cs b/tests/MyGame/MonsterExtra.cs
index 63a689a31..4b0f8de01 100644
--- a/tests/MyGame/MonsterExtra.cs
+++ b/tests/MyGame/MonsterExtra.cs
@@ -191,10 +191,15 @@ public class MonsterExtraT
}
public static MonsterExtraT DeserializeFromJson(string jsonText) {
- return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText);
+ return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ });
}
public string SerializeToJson() {
- return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ Formatting = Newtonsoft.Json.Formatting.Indented,
+ });
}
public static MonsterExtraT DeserializeFromBinary(byte[] fbBuffer) {
return MonsterExtra.GetRootAsMonsterExtra(new ByteBuffer(fbBuffer)).UnPack();
diff --git a/tests/namespace_test/NamespaceA/JsonContractResolver.cs b/tests/namespace_test/NamespaceA/JsonContractResolver.cs
new file mode 100644
index 000000000..519943238
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/JsonContractResolver.cs
@@ -0,0 +1,28 @@
+//
+// automatically generated by the FlatBuffers compiler, do not modify
+//
+
+namespace NamespaceA
+{
+
+using global::System;
+using global::System.Collections.Generic;
+using global::Google.FlatBuffers;
+
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
+
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/JsonContractResolver.cs b/tests/namespace_test/NamespaceA/NamespaceB/JsonContractResolver.cs
new file mode 100644
index 000000000..6aedab71a
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/JsonContractResolver.cs
@@ -0,0 +1,28 @@
+//
+// automatically generated by the FlatBuffers compiler, do not modify
+//
+
+namespace NamespaceA.NamespaceB
+{
+
+using global::System;
+using global::System.Collections.Generic;
+using global::Google.FlatBuffers;
+
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
+
+}
diff --git a/tests/nested_namespace_test/nested_namespace_test1_generated.cs b/tests/nested_namespace_test/nested_namespace_test1_generated.cs
index f1e646c42..f9eee17ee 100644
--- a/tests/nested_namespace_test/nested_namespace_test1_generated.cs
+++ b/tests/nested_namespace_test/nested_namespace_test1_generated.cs
@@ -9,6 +9,21 @@ using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum Color : sbyte
{
diff --git a/tests/nested_namespace_test/nested_namespace_test2_generated.cs b/tests/nested_namespace_test/nested_namespace_test2_generated.cs
index efd2584dd..c545459c9 100644
--- a/tests/nested_namespace_test/nested_namespace_test2_generated.cs
+++ b/tests/nested_namespace_test/nested_namespace_test2_generated.cs
@@ -9,6 +9,21 @@ using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum Color : sbyte
{
diff --git a/tests/nested_namespace_test/nested_namespace_test3_generated.cs b/tests/nested_namespace_test/nested_namespace_test3_generated.cs
index 32be9bede..0f95186c5 100644
--- a/tests/nested_namespace_test/nested_namespace_test3_generated.cs
+++ b/tests/nested_namespace_test/nested_namespace_test3_generated.cs
@@ -9,6 +9,21 @@ using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
public struct ColorTestTable : IFlatbufferObject
{
private Table __p;
diff --git a/tests/union_value_collsion/union_value_collision_generated.cs b/tests/union_value_collsion/union_value_collision_generated.cs
index e741e9afb..81009e451 100644
--- a/tests/union_value_collsion/union_value_collision_generated.cs
+++ b/tests/union_value_collsion/union_value_collision_generated.cs
@@ -9,6 +9,21 @@ using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum Value : byte
{
@@ -498,10 +513,15 @@ public class CollisionT
}
public static CollisionT DeserializeFromJson(string jsonText) {
- return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText);
+ return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ });
}
public string SerializeToJson() {
- return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ Formatting = Newtonsoft.Json.Formatting.Indented,
+ });
}
public static CollisionT DeserializeFromBinary(byte[] fbBuffer) {
return Collision.GetRootAsCollision(new ByteBuffer(fbBuffer)).UnPack();
diff --git a/tests/union_vector/JsonContractResolver.cs b/tests/union_vector/JsonContractResolver.cs
new file mode 100644
index 000000000..ea8209240
--- /dev/null
+++ b/tests/union_vector/JsonContractResolver.cs
@@ -0,0 +1,23 @@
+//
+// automatically generated by the FlatBuffers compiler, do not modify
+//
+
+using global::System;
+using global::System.Collections.Generic;
+using global::Google.FlatBuffers;
+
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+class JsonReadOnlyAttribute : Attribute {
+}
+
+public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+ protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+ if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
+ property.Readable = false;
+ return property;
+ }
+}
+
diff --git a/tests/union_vector/Movie.cs b/tests/union_vector/Movie.cs
index 8e75f7c53..cf292fc92 100644
--- a/tests/union_vector/Movie.cs
+++ b/tests/union_vector/Movie.cs
@@ -197,10 +197,15 @@ public class MovieT
}
public static MovieT DeserializeFromJson(string jsonText) {
- return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText);
+ return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ });
}
public string SerializeToJson() {
- return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
+ ContractResolver = new JsonContractResolver(),
+ Formatting = Newtonsoft.Json.Formatting.Indented,
+ });
}
public static MovieT DeserializeFromBinary(byte[] fbBuffer) {
return Movie.GetRootAsMovie(new ByteBuffer(fbBuffer)).UnPack();