Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#将Json反序列化到模型中,并将特殊属性添加到列表中_C#_Json - Fatal编程技术网

C#将Json反序列化到模型中,并将特殊属性添加到列表中

C#将Json反序列化到模型中,并将特殊属性添加到列表中,c#,json,C#,Json,我试图在模型类中添加某种属性,以便在json反序列化期间,如果某个键是某种格式(在本例中,以\u special结尾),它将被添加到模型的列表中 即: C# 因此结果将是:MyModel.Name==“John”和MyModel.SpecialFields将是身高和体重的键值对 这可能吗 编辑:项目使用.NET Core 3.1和System.Text.Json,可以通过以下步骤实现: 为Json字段创建类型: public class SpecialClass { public str

我试图在模型类中添加某种属性,以便在json反序列化期间,如果某个键是某种格式(在本例中,以
\u special
结尾),它将被添加到模型的列表中

即: C#

因此结果将是:
MyModel.Name==“John”
MyModel.SpecialFields
将是身高和体重的键值对

这可能吗


编辑:项目使用.NET Core 3.1和System.Text.Json,可以通过以下步骤实现:

为Json字段创建类型:

public class SpecialClass
{
    public string Name { get; set; }
    public string Height_Special { get; set; }
    public string Weight_Special { get; set; }
}
使用以下类型转换Json:

var myObject = JsonConvert.DeserializeObject<SpecialClass>(yourJson);

您可以使用
System.Text.JSON
的自定义JSON转换器来实现这一点。下面是一个可扩展的示例,它适合您特定的
MyModel
类:

var jsonString = JsonSerializer.Serialize<MyModel>(model, options);
公共类MyModelJsonConverter:JsonConverter
{
公共覆盖MyModel读取(参考Utf8JsonReader,
类型转换,
JsonSerializerOptions(可选)
{
MyModel模型=新的MyModel()
{
SpecialFields=新字典()
};
string-nextPropertyName=string.Empty;
while(reader.Read())
{
开关(reader.TokenType)
{
案例JsonTokenType.PropertyName:
nextPropertyName=reader.GetString();
打破
案例JsonTokenType.String:
//这里尝试使用反射或切换,但是if/else if执行得更快
if(nextPropertyName==“Name”)
{
model.Name=reader.GetString();
继续;
}
//确保它是一个_特殊字段;如果不是,则无法识别!
int-nameEndsAtIndex=nextPropertyName.IndexOf(“_-special”);
如果(nameEndsAtIndex==-1)抛出新的InvalidDataException(“未知JSON字段”);
string key=nextPropertyName.Substring(0,nameEndsAtIndex);
字符串值=reader.GetString();
model.SpecialFields.Add(key,value);
打破
}
}
收益模型;
}
公共重写无效写入(Utf8JsonWriter,
我的模型值,
JsonSerializerOptions(可选)
{
writer.WritePropertyName(“名称”);
writer.WriteStringValue(value.Name);
foreach(值中的变量specialField.SpecialFields)
{
writer.WritePropertyName($“{specialField.Key}\u special”);
writer.WriteStringValue(specialField.Value);
}
}
}
这可以按如下方式使用:

var options=new JsonSerializerOptions()
{ 
转换器={new MyModelJsonConverter()}
};
var model=JsonSerializer.Deserialize(jsonString,选项);
注意,此自定义转换器可以往返于您的
MyModel
类:

var jsonString = JsonSerializer.Serialize<MyModel>(model, options);
var jsonString=JsonSerializer.Serialize(模型,选项);
为了在ASP.NET Core应用程序或Web API中使用此设置,您需要向模型类添加一个属性,以便让ASP.NET Core framework知道您打算使用自定义转换器:

[JsonConverter(typeof(MyModelJsonConverter))]
公共类MyModel
{
公共字符串名称{get;set;}
公共IDictionary特殊字段{get;set;}
}
…而且,就像那样,转换将自动处理


我强烈建议您逐步使用带有断点的
Read
Write
方法,以真正了解下面发生的事情。这些方法将由
JsonSerializer
直接调用;通过了解这些如何工作,您可以了解如何扩展此自定义转换器(如果您需要这样做)。

是的,使用自定义JSON转换器:另外,您能否提供更多有关在何处使用此转换器的详细信息?听起来这是一个基于web的应用程序或API;我可以假定它是ASP.NET核心。如果是,版本是什么?您是使用JSON.NET还是新的
System.Text.JSON
进行反序列化?缺少这些细节可能是为什么有人刚刚否决了你的帖子,也许更重要的是,为什么有人很难帮助你-我们需要做很多猜测工作。。。请用更相关的细节来澄清你的问题。非常感谢。谢谢你的帮助。将这些细节添加到问题中,对于
System.Text.Json
,这是一个更好的资源:这实际上是手动的-为什么不使用为此目的而设计的自定义转换器?还有,为什么您的
词典是
?你的意思是《词典》
,正如他们在帖子中提到的那样?为什么要从对象的宽度映射到高度?OP想要从属性名映射到属性值-如果你打算保留它,请你更正你的帖子好吗?@CoolBots你提到的要点是使用int而不是string不是什么大问题。用户可以理解它。无论如何,我已经更新了答案。如果不使用自定义转换器,并不意味着此解决方案是错误的。它也在起作用。如果解决方案是经典形式,那么就不是否决它的正当理由;你搞定了,所以我取消了否决票。在这种情况下,你的“经典形式”(无论这意味着什么)方法类似于通过车窗进入汽车-它起作用。。。
var dictionary = new Dictionary<string, string>()
{
    { myObject.Height_Special, myObject.Weight_Special }
};
var dictionary = new Dictionary<string, string>()
{
    { nameof(myObject.Height_Special), myObject.Height_Special },
    { nameof(myObject.Weight_Special), myObject.Weight_Special }
};
MyModel myModel = new MyModel()
{
    Name = myObject.Name,
    SpecialFields = dictionary,
};
var jsonString = JsonSerializer.Serialize<MyModel>(model, options);