AspNet 3.1 - 与另一个碰撞 属性 : ThrowInvalidOperationException_SerializerPropertyNameConflict
AspNet 3.1 - Collides with another property : ThrowInvalidOperationException_SerializerPropertyNameConflict
我的错误是控制器无法映射值;我有这种情况可以解释如何复制错误:
public class FooA {
public string Property1 { set; get; }
public virtual string Property2 { set; get; }
}
public class FooB : FooA {
public new string Property2 { set; get; }
public string Property3 { set; get; }
}
如您所知,属性 Property2 对于两个 classes 都是通用的,因此当您在任何控制器中使用此操作时:
public async task<string> ActionA([FromBody] FooA fooA)
{
return string.Empty;
}
// The error is thrown in this unwrapping.
public async task<string> ActionB([FromBody] FooB fooB)
{
return string.Empty;
}
请求的 FooA 负载是:
{
"Property1" : "abc",
"Property2" : "def"
}
请求的 FooB 负载是:
{
"Property2" : "abc",
"Property3" : "def"
}
将抛出此异常:
System.InvalidOperationException: The JSON property name for 'FooB' collides with another property.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(JsonClassInfo jsonClassInfo, JsonPropertyInfo jsonPropertyInfo)
at System.Text.Json.JsonClassInfo..ctor(Type type, JsonSerializerOptions options)
我已经添加了诸如 [JsonIgnore]
之类的属性,但是它失败了,就像第一个一样。
或:
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = null;
options.JsonSerializerOptions.PropertyNameCaseInsensitive = false;
});
但这不可能,我的想法是要SOLID,避免改变整个解决方案。 It means Open Extensions (这意味着扩展将解决未来的问题) Closed to (already implemented) changes.
您是否在 AddJsonOptions 中进行了特定设置以允许始终使用子 class 自动解决继承冲突?
注意事项 01:即使添加了 virtual ans new reserver 关键字,控制器也会抛出相同的异常。
你必须修复 类,你有 2 个选择
普通的
public class FooA
{
public string Property1 { set; get; }
public virtual string Property2 { set; get; }
}
public class FooB : FooA
{
public override string Property2 { set; get; }
public string Property3 { set; get; }
}
或者如果您想访问 2 个属性
public class FooA
{
public string Property1 { set; get; }
public string Property2 { set; get; }
}
public class FooB : FooA
{
public new string Property2 { set; get; }
public string Property3 { set; get; }
}
测试
var json = @"{
""Property2"" : ""abc"",
""Property3"" : ""def""
}";
var jsonDeserialized=System.Text.Json.JsonSerializer.Deserialize<FooB>(json);
测试结果(json格式)
{
"Property2": "abc",
"Property3": "def",
"Property1": null
}
但我建议您安装 Newtonsoft.Json 序列化程序
只需在启动时配置它
using Newtonsoft.Json.Serialization;
services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());
或者如果您只使用控制器
services.AddControllers()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());
我的错误是控制器无法映射值;我有这种情况可以解释如何复制错误:
public class FooA {
public string Property1 { set; get; }
public virtual string Property2 { set; get; }
}
public class FooB : FooA {
public new string Property2 { set; get; }
public string Property3 { set; get; }
}
如您所知,属性 Property2 对于两个 classes 都是通用的,因此当您在任何控制器中使用此操作时:
public async task<string> ActionA([FromBody] FooA fooA)
{
return string.Empty;
}
// The error is thrown in this unwrapping.
public async task<string> ActionB([FromBody] FooB fooB)
{
return string.Empty;
}
请求的 FooA 负载是:
{
"Property1" : "abc",
"Property2" : "def"
}
请求的 FooB 负载是:
{
"Property2" : "abc",
"Property3" : "def"
}
将抛出此异常:
System.InvalidOperationException: The JSON property name for 'FooB' collides with another property.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(JsonClassInfo jsonClassInfo, JsonPropertyInfo jsonPropertyInfo)
at System.Text.Json.JsonClassInfo..ctor(Type type, JsonSerializerOptions options)
我已经添加了诸如 [JsonIgnore]
之类的属性,但是它失败了,就像第一个一样。
或:
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = null;
options.JsonSerializerOptions.PropertyNameCaseInsensitive = false;
});
但这不可能,我的想法是要SOLID,避免改变整个解决方案。 It means Open Extensions (这意味着扩展将解决未来的问题) Closed to (already implemented) changes.
您是否在 AddJsonOptions 中进行了特定设置以允许始终使用子 class 自动解决继承冲突?
注意事项 01:即使添加了 virtual ans new reserver 关键字,控制器也会抛出相同的异常。
你必须修复 类,你有 2 个选择
普通的
public class FooA
{
public string Property1 { set; get; }
public virtual string Property2 { set; get; }
}
public class FooB : FooA
{
public override string Property2 { set; get; }
public string Property3 { set; get; }
}
或者如果您想访问 2 个属性
public class FooA
{
public string Property1 { set; get; }
public string Property2 { set; get; }
}
public class FooB : FooA
{
public new string Property2 { set; get; }
public string Property3 { set; get; }
}
测试
var json = @"{
""Property2"" : ""abc"",
""Property3"" : ""def""
}";
var jsonDeserialized=System.Text.Json.JsonSerializer.Deserialize<FooB>(json);
测试结果(json格式)
{
"Property2": "abc",
"Property3": "def",
"Property1": null
}
但我建议您安装 Newtonsoft.Json 序列化程序 只需在启动时配置它
using Newtonsoft.Json.Serialization;
services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());
或者如果您只使用控制器
services.AddControllers()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());