まず、標準json形式でシリアル化する必要があります。あなたがやっていることは、オブジェクトをシリアライズしてファイルに書き込むことです。それは、リストをjson形式にシリアライズする必要があったはずです。 しかし、具体的な理由があると仮定すると、さまざまなシナリオでさまざまな解決策を提示しています。
注:私はNewtonsoft.Jsonを使用しましたが、これは高速ですし、とても簡単です。 http://www.newtonsoft.com/json
https://www.nuget.org/packages/newtonsoft.json/
ソリューション:
//Class for testing object
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
}
解決方法1:推奨
/// <summary>
/// Serializing the list in single go
/// </summary>
public void Serialize()
{
List<Account> listOfAccounts = new List<Account>();
listOfAccounts.Add(new Account { Id = 1, Name = "First" });
listOfAccounts.Add(new Account { Id = 2, Name = "Second" });
listOfAccounts.Add(new Account { Id = 3, Name = "Third" });
string outputJSON = Newtonsoft.Json.JsonConvert.SerializeObject(listOfAccounts, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(@"c:\temp\data.json", outputJSON + Environment.NewLine);
}
/// <summary>
/// Serializing the list, one by one object
/// Comma is appended to every object in json format
/// Finally, enclosed it with [ and ] to make it array of objects
/// </summary>
public void Serialize2()
{
List<Account> listOfAccounts = new List<Account>();
listOfAccounts.Add(new Account { Id = 1, Name = "First" });
listOfAccounts.Add(new Account { Id = 2, Name = "Second" });
listOfAccounts.Add(new Account { Id = 3, Name = "Third" });
string outputJSON = "";
foreach(var item in listOfAccounts)
{
outputJSON += Newtonsoft.Json.JsonConvert.SerializeObject(item, Newtonsoft.Json.Formatting.Indented)+",";
}
File.WriteAllText(@"c:\temp\data.json", "["+outputJSON + "]");
}
/// <summary>
/// Read serialized data into list of objects
/// </summary>
public void DeSerialize()
{
if (File.Exists(@"c:\temp\data.json"))
{
String JSONtxt = File.ReadAllText(@"c:\temp\data.json");
var accounts = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<Account>>(JSONtxt);
}
}
解決方法2:あなたの要件ごと
/// <summary>
/// Non standard json serialization (object one by one) Highly discouraged unless you have specific reason
/// Assuming the output will not have internal objects
/// </summary>
public void SerializeNonStandard()
{
List<Account> listOfAccounts = new List<Account>();
listOfAccounts.Add(new Account { Id = 1, Name = "First" });
listOfAccounts.Add(new Account { Id = 2, Name = "Second" });
listOfAccounts.Add(new Account { Id = 3, Name = "Third" });
foreach (var item in listOfAccounts)
{
string outputJSON = Newtonsoft.Json.JsonConvert.SerializeObject(item, Newtonsoft.Json.Formatting.Indented);
File.AppendAllText(@"c:\temp\data-ns.json", outputJSON + Environment.NewLine);
}
}
/// <summary>
/// Deserializes the list in one by one fashion and appends to list
/// </summary>
public void DeSerializeNonStandard()
{
if (File.Exists(@"c:\temp\data-ns.json"))
{
List<Account> listOfAccounts = new List<Account>();
String JSONtxt = File.ReadAllText(@"c:\temp\data-ns.json");
//Capture JSON string for each object, including curly brackets
Regex regex = new Regex(@".*(?<=\{)[^}]*(?=\}).*", RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(JSONtxt);
foreach(Match match in matches)
{
string objStr = match.ToString();
Account account = Newtonsoft.Json.JsonConvert.DeserializeObject<Account>(objStr);
listOfAccounts.Add(account);
}
}
}
/// <summary>
/// Deserializes the non standard json to list of accounts
/// Splits the object strings, merges with comma and encloses with [] to make it array of objects format and deserializes
/// </summary>
public void DeSerializeNonStandardList()
{
if (File.Exists(@"c:\temp\data-ns.json"))
{
String JSONtxt = File.ReadAllText(@"c:\temp\data-ns.json");
//Capture JSON string for each object, including curly brackets
Regex regex = new Regex(@".*(?<=\{)[^}]*(?=\}).*", RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(JSONtxt);
string joinedJSON = string.Join(",", matches.Cast<Match>().Select(m => m.Value));
joinedJSON = string.Format("[{0}]", joinedJSON);
var listOfAccounts = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<Account>>(joinedJSON);
}
}
ただ新しい行を追加することはできません。 jsonファイル内の配列にすべてのアカウントをラップする必要があります。これを達成するためにリスト全体を直列化することができます。各アカウントをループして手動で行う必要はありません。 –
@DevonSutherlandは、コレクション全体をよりシリアライズしてデシリアライズできると述べています。それが動作します。 – Adrian
@DevonSutherlandのシリアル化プロセスは正常に動作します。新しい行は各Accountオブジェクトを単に分離するので、jsonファイルを開いて読むことができます。私が達成できないことは、データをリストに戻すことです。 –