问题介绍:
两个类型
// 同步数据,包含用户数据
public class SysMessage
{
public int dti { get; set; }
public UserData playerJMsg { get; set; }
}
// 用户数据
public class UserData
{
public string playerId{ get; set; } //数字ID
public string email{ get; set; }//邮箱
public int excution { get; set; }//体力
public long gold { get; set; }//游戏币
}
SysMessage类型一般是心跳返回的,而且心跳返回的数据不是完整数据,只会同步某些字段,比如只同步 UserData中的gold.
我在收到服务器的json数据后,都是直接解析成类的
SysMessage data = JsonMapper.ToObject<SysMessage>(@request.downloadHandler.text);
然而类的解析后 ,一些不需要同步的字段初始化了,也就是会出现 email是null, excution是0
导致不知道是不是需要同步的字段,我们只需要同步json数据中包含的字段就可以了
解决方法
sys1 是直接收到的json数据转JsonData : JsonMapper.ToObject(@request.downloadHandler.text)["sysMessage"]
这里用的unityWebRequest请求的json数据
var sys = sys1 as JsonData;
if (m_user == null) m_user = JsonMapper.ToObject<UserData>(sys["playerJMsg"].ToJson());
else
{
try
{
var player = sys["playerJMsg"];
// 合并user数据
foreach (var p in m_user.GetType().GetProperties())
{
try
{
if (null != player[p.Name])
{// 需要同步数据
if (p.Name == "pet")
{// 是一个类型
p.SetValue(m_user, JsonMapper.ToObject<HeroData>(JsonMapper.ToJson(player[p.Name])));
}
else
{// 判断原始数据类型,否则转换可能失败
if (p.PropertyType.Name == "String")
{
p.SetValue(m_user, player[p.Name].ToString());
}
else if (p.PropertyType.Name == "Int64")
{
p.SetValue(m_user, Convert.ToInt64(player[p.Name].ToString()));
}
else if (p.PropertyType.Name == "Int32")
{
p.SetValue(m_user, Convert.ToInt32(player[p.Name].ToString()));
}
}
}
}
catch
{
Console.WriteLine("playerJMsg not found "+ p.Name);
}
}
}
catch (FormatException)
{
Console.WriteLine("sys not found playerJMsg");
}
}
这里使用try catch是因为 jsonData一旦是一个不包含key就马上报错,比如 sys中不包含字段playerMsg,如果直接使用sys["playerMsg"]就会报错,这里是尝试获取我们需要的字段
System.Collections.Generic.KeyNotFoundException: The given key was not present i
这样就做到了,只同步有的数据,防止json直接转class导致的默认值问题,分不清哪些是同步过来的