Json.Net序列化类名而不是内部属性

时间:2015-12-01 13:14:20

标签: c# json.net

这是代码:

-(void)textFieldDidBeginEditing:(UITextField *)textField  {




if ([textField viewWithTag:100]) {

    [textField resignFirstResponder];
    [self.View1 setHidden:NO];
    variable=1;
}

......这是Json的结果。请注意,它显示了类名 [textField resignFirstResponder]; [self.View1 setHidden:NO]; variable=2; } [_Picker_view reloadAllComponents]; 而不是其参数,而这些参数并不在我的代码中。

public class ParameterDictionary : Dictionary<HydroObjectIdentifier, string>
{

    public void WriteToJson(string jsonFilePath)
    {
        string json = Newtonsoft.Json.JsonConvert.SerializeObject(this, formatting: Newtonsoft.Json.Formatting.Indented);
        System.IO.File.WriteAllText(jsonFilePath, json);
    }

}

public struct HydroObjectIdentifier
{

    public string Name { get; set; }
    public string TypeName { get; set; }

    public HydroObjectIdentifier(string name, string typeName)
    {
        this.Name = name;
        this.TypeName = typeName;
    }

}

如评论中所述,预期的行为是将Name和TypeName写入json,而不是类的名称。

2 个答案:

答案 0 :(得分:5)

您看到此行为的原因是因为您使用复杂对象(HydroObjectIdentifier)作为词典中的键。在JSON中,对象键必须始终为字符串,每the spec。当Json.Net尝试序列化字典时,它会发现您的密钥不是字符串。由于它需要一个字符串,因此只需在您的类上调用ToString()即可。 C#中ToString()的默认实现返回类型的名称,在您的情况下为RSEngine.HydroObjectIdentifier

如果您实施自己的ToString()方法,正如另一个答案中所建议的那样,那么您可以根据问题制作密钥。但是,这种方法的缺点是您无法将JSON反序列化回字典。这是因为没有相反的“FromString”方法,Json.Net可以使用该方法将序列化密钥从字符串转换回标识符类。如果您需要使用JSON进行全程往返(序列化和反序列化),那么您将需要一个不同的解决方案。

在Json.Net中有几种可能的方法来处理复杂的字典键:

  1. 为您的标识符类实施TypeConverter,如Json.Net Serialization Guide中所述。有关详细信息,请参阅MSDN中的How to: Implement a Type Converter。实现类型转换器后,您需要使用[TypeConverter]属性标记您的类,以便Json.Net知道使用它。
  2. 使用自定义JsonConverter作为字典,更改键值对如何写入JSON。有关该方法的示例,请参阅How To Serialize a class that derives from a Dictionary

答案 1 :(得分:3)

尝试覆盖ToString()方法:

public struct HydroObjectIdentifier
{

    public string Name { get; set; }
    public string TypeName { get; set; }

    public override string ToString()
    {
        return Newtonsoft.Json.JsonConvert.SerializeObject(this);
    }

    public HydroObjectIdentifier(string name, string typeName)
    {
        this.Name = name;
        this.TypeName = typeName;
    }

}