2014-07-13 1 views
2

의 클래스 내에서 다른 클래스를 참조하는 규칙을 만들내가 두 개의 저장소를 채울 내 서비스 클래스 생성자에서 JSON

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(); 

저장소에 규칙을 추가 인터페이스 방법 (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" 
    } 
] 

클래스가 직렬화

,617,451되는 직렬화 889,003,210

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; 
} 

인터페이스 방법

경고 1 개만 최상위 배열 또는 개체입니다 JSON 문서에서 허용된다 : 515,

// 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가 날을 제공하더라도 적절한 포맷하지 않다.

그리고 실제로 그것은 단지 다른 BackupRule 객체에서 만든 다른 BackupPaths 참조 직렬화 BackupPath 클래스를 참조하지 않습니다. 내가 어디서 잘못 됐어? 이상적으로 그것은 목록에서 두 개의 "테이블"을 만들고 BackupRule 참조를 예와 비슷하지만 BackupRule # 2를 참조하는 것보다 BackupPaths 참조를 가지고 싶습니다. 은 BackupRule # 1에 저장됩니다. 오히려 둘 다 직렬화 된 BackupPath "테이블"을 참조하십시오. 또한 이상적으로 하나의 json 파일에 직렬화 된 목록을 둘 다 저장하고 싶습니다. 그러나 이것에 대해 유연합니다. 이 때문에

답변

3

이 경고에 관해서는, 그건 :

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

를 경고가 말한대로, JSON 정말 단 한 최상위 요소를 가질 수 있고 당신이 개 최상위 요소를 작성했습니다. 경고 멀리 갈 수 있도록하기 위해, 당신은 하나의 객체로 rulespaths 포장 수 :

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

+0

이 실제로 문제를 완전히 해결했다. Paths를 먼저 직렬화하는 한, 규칙은 경로를 참조합니다 :'serializer.Serialize (jsonWriter, new {Paths = paths, Rules = rules});'다른 사람이 좀 더 안정적/효율적으로 응답하는지 기다릴 것입니다. 솔루션으로 표시하기 전에 – aaronmallen

관련 문제