我正在尝试读取和写入文件。 对于第一部分,将对象列表写入二进制文件,我使用序列化成功完成。
问题是当我尝试使用deserialize从文件中读回对象列表时。每次我运行解决方案时都会出现运行时错误。
代码:
using System;
using System.IO;
using MileStone1Fin.LogicLayer;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Newtonsoft.Json;
namespace MileStone1Fin.PersistentLayer
{
public class UserHandler
{
public UserHandler()
{
}
public void addNewUser(List<User> users)
{
Stream myFileStream = File.Create("UsersData.bin");
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(myFileStream, users);
Console.WriteLine("5535");
myFileStream.Close();
List<User> newUsers1 = null;
if (File.Exists("UsersData.bin"))
{
Stream myFileStream1 = File.OpenRead("UsersData.bin");
BinaryFormatter bf1 = new BinaryFormatter();
newUsers1 = (List<User>)bf1.Deserialize(myFileStream1);//this line marked as the problem one according to visual studio
myFileStream1.Close();
}
}
}
}
第38行是有问题的一行 拨打电话的代码:
public void registration(String nickname, String groupID)
{
if(checkUserValidity(nickname, groupID))
{
User newUser = new User(nickname, groupID);
users.Add(newUser);
userHandler.addNewUser(users);
User class:
System.Reflection.TargetInvocationExeption - the runtime error
using System;
using Newtonsoft.Json;
using MileStoneClient.CommunicationLayer;
using MileStone1Fin.PersistentLayer;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace MileStone1Fin.LogicLayer
{
///<summary>
/// This class taking care for the functionallity of the user objects.
/// The user class will be part of the Logic layer
/// </summary>
[Serializable()]
public class User : ISerializable
{
private static UserHandler userHandler = new UserHandler();
private String nickname { get; set; }
private String groupID { get; set; }
private bool status { get; set; }
DateTime lastSeen { get; set; }
public User(String nickname, String groupID) //The User class constructor
{
this.nickname = nickname;
this.groupID = groupID;
this.lastSeen = DateTime.Now;
this.status = false;
}
/*public Message send(String msg) //Creates a Imessage object, return a Message object contains GUID, time, user
{ //information, message body
IMessage message = Communication.Instance.Send(ChatRoom.url, this.groupID, this.nickname, msg);//sends the neccesary details to the server
return new Message(message);
}*/
public void logout()
{
this.status = false;
//Console.WriteLine(this.nickname + "You were disconnected from the server");
lastSeen = DateTime.Now;
//Console.WriteLine(lastSeen);
//need to write into file
}
private bool isOnline()
{
return this.status;
}
public void lastSeenDate()
{
if (isOnline())
Console.WriteLine("Online now");
else
Console.WriteLine(lastSeen.ToString());
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Nickname", nickname);
info.AddValue("GroupId", groupID);
info.AddValue("LastSeen", lastSeen);
info.AddValue("Status", status);
}
public User(SerializationInfo info, StreamingContext context)
{
nickname = (string)info.GetValue("Name", typeof(string));
groupID = (string)info.GetValue("GroupId", typeof(string));
lastSeen = (DateTime)info.GetValue("LastSeen", typeof(DateTime));
status = (Boolean)info.GetValue("Status", typeof(Boolean));
}
}
}
答案 0 :(得分:1)
问题在于您如何使用序列化来命名,您正在序列化Nickname
并尝试将其读作Name
。最安全的做法是从酒店获得正确的名称:
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(nickname), nickname);
info.AddValue(nameof(groupID), groupID);
info.AddValue(nameof(lastSeen), lastSeen);
info.AddValue(nameof(status), status);
}
public User(SerializationInfo info, StreamingContext context)
{
nickname = (string)info.GetValue(nameof(nickname), typeof(string));
groupID = (string)info.GetValue(nameof(groupID), typeof(string));
lastSeen = (DateTime)info.GetValue(nameof(lastSeen), typeof(DateTime));
status = (Boolean)info.GetValue(nameof(status), typeof(Boolean));
}
}
当您重命名属性(符合.NET标准)时,它会带来额外的好处,它也会自动重命名您的代码。如果您重命名某些内容然后尝试加载旧文件,这可能会导致问题,所以要小心,但至少这样您的代码中没有漂浮的魔术字符串。您可以通过将版本信息写入序列化流并根据版本进行反序列化来避免上述问题。