在json的类中引用另一个类

时间:2014-07-13 01:35:18

标签: c# asp.net json serialization json.net

在我的服务类构造函数中,我填充了两个存储库:

private List<BackupRule> rules;
private List<BackupPath> paths;

public RuleService()
{
  List<BackupRule> _rules = new List<BackupRule>();
  List<BackupPath> _paths = new List<BackupPath>();
  using (var wc = new System.Net.WebClient())
  {
    string json = wc.DownloadString(jsonRuleFile);
    if (json.Length > 0)
    {
      _rules = JsonConvert.DeserializeObject<List<BackupRule>>(json);
      _paths = JsonConvert.DeserializeObject<List<BackupPath>>(json);
    }
  }
  rules = _rules;
  paths = _paths;
}

然后我尝试创建规则并将规则添加到存储库:

创建规则的代码

IRuleService db = new RuleService();
List<BackupPath> paths = new List<BackupPath>();
paths.Add(new BackupPath { Type = PathType.Source, Value = "C:\\Test\\" });
paths.Add(new BackupPath { Type = PathType.Destination, Value = "C:\\Test\\" });
paths.Add(new BackupPath { Type = PathType.Source, Value = "C:\\Test\\" });
paths.Add(new BackupPath { Type = PathType.Source, Value = "C:\\Test\\" });
BackupRule rule1 = new BackupRule() { Name = "test1", Type = RuleType.Archive, UserName = System.Environment.UserName, Paths = paths, EndOfDay = true, Created = DateTime.Now};
BackupRule rule2 = new BackupRule() { Name = "test2", Type = RuleType.Archive, UserName = System.Environment.UserName, Paths = paths, EndOfDay = true, Created = DateTime.Now };
db.CreateRule(rule1);
db.CreateRule(rule2);
db.SaveChanges();

接口将规则添加到存储库的方法

public BackupRule CreateRule(BackupRule rule)
{
  if (rules.Any(r => r.Name == rule.Name))
  {
    return null;
  }
  rule.Paths = rule.Paths.OrderBy(p => p.Type.GetHashCode()).ToList();
  foreach (BackupPath path in rule.Paths)
  {
    path.Id = (paths.Count() == 0) ? 1 : paths.LastOrDefault().Id + 1;
    paths.Add(path);
  }
  rule.Id = (rules.Count() == 0) ? 1 : rules.LastOrDefault().Id + 1;
  rules.Add(rule);
  rules = rules.OrderBy(r => r.Id).ToList();
  return rule;
}

将(sic?)序列化为json

的接口方法
public void SaveChanges()
{
  using (FileStream fileStream = File.Open(@jsonRuleFile, FileMode.OpenOrCreate))
  using (StreamWriter streamWriter = new StreamWriter(fileStream))
  using (JsonWriter jsonWriter = new JsonTextWriter(streamWriter))
  {
    jsonWriter.Formatting = Formatting.Indented;

    JsonSerializer serializer = new JsonSerializer();
    serializer.Serialize(jsonWriter, rules);
    serializer.Serialize(jsonWriter, paths);
  }
}

json输出

[
  {
    "Id": 1,
    "Name": "test1",
    "UserName": "Aaron",
    "rule_type": "Archive",
    "Paths": [
      {
        "$id": "1",
        "Id": 5,
        "Value": "C:\\Test\\",
        "Type": "Source"
      },
      {
        "$id": "2",
        "Id": 6,
        "Value": "C:\\Test\\",
        "Type": "Source"
      },
      {
        "$id": "3",
        "Id": 7,
        "Value": "C:\\Test\\",
        "Type": "Source"
      },
      {
        "$id": "4",
        "Id": 8,
        "Value": "C:\\Test\\",
        "Type": "Destination"
      }
    ],
    "EndOfDay": true,
    "Created": "2014-07-12T20:14:03.9126784-05:00"
  },
  {
    "Id": 2,
    "Name": "test2",
    "UserName": "Aaron",
    "rule_type": "Archive",
    "Paths": [
      {
        "$ref": "1"
      },
      {
        "$ref": "2"
      },
      {
        "$ref": "3"
      },
      {
        "$ref": "4"
      }
    ],
    "EndOfDay": true,
    "Created": "2014-07-12T20:14:03.9126784-05:00"
  }
][
  {
    "Id": 5,
    "Value": "C:\\Test\\",
    "Type": "Source"
  },
  {
    "Id": 6,
    "Value": "C:\\Test\\",
    "Type": "Source"
  },
  {
    "Id": 7,
    "Value": "C:\\Test\\",
    "Type": "Source"
  },
  {
    "Id": 8,
    "Value": "C:\\Test\\",
    "Type": "Destination"
  },
  {
    "Id": 5,
    "Value": "C:\\Test\\",
    "Type": "Source"
  },
  {
    "Id": 6,
    "Value": "C:\\Test\\",
    "Type": "Source"
  },
  {
    "Id": 7,
    "Value": "C:\\Test\\",
    "Type": "Source"
  },
  {
    "Id": 8,
    "Value": "C:\\Test\\",
    "Type": "Destination"
  }
]

正在序列化的类

// using statements added to post to help 
// reader understand I am using Json.Net
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public class BackupRule
{
  [JsonProperty]
  public int Id { get; set; }
  [JsonProperty]
  public string Name { get; set; }
  public string UserName { get; set; }
  [JsonProperty(PropertyName = "rule_type")]
  [JsonConverter(typeof(StringEnumConverter))]
  public RuleType Type { get; set; }
  [JsonProperty(ItemIsReference = true)]
  public List<BackupPath> Paths { get; set; }
  public bool EndOfDay { get; set; }
  public DateTime Created { get; set; }
}
public class BackupPath
{
  public int Id { get; set; }
  public string Value { get; set; }
  [JsonConverter(typeof(StringEnumConverter))]
  public PathType Type { get; set; }
}

问题是json甚至不是它给我的正确格式:

  

警告1 JSON文档中只允许使用一个顶级数组或对象。

它实际上并没有引用序列化的BackupPath类,它只引用在其他BackupPaths对象中创建的其他BackupRule。我在哪里错了?理想情况下,我希望它能够在列表中创建两个“表格”并让BackupRule引用BackupPaths“表格”,就像在第二个BackupRule示例中那样,而不是{ {1}}#2引用存储在BackupRule#1中的BackupPath我宁愿同时引用序列化的BackupRule“表格”。理想情况下,我想将两个序列化列表存储在一个json文件中,但我对此很灵活。

1 个答案:

答案 0 :(得分:3)

关于警告,那是因为你有这个:

serializer.Serialize(jsonWriter, rules);
serializer.Serialize(jsonWriter, paths);

正如警告所说,JSON真的只能有1个顶级元素而你已经编写了2个顶级元素。要使警告消失,您可以将rulespaths包装到单个对象中:

serializer.Serialize(jsonWriter, new {Rules = rules, Paths = paths});