在 Unity3D 上使用 NewtonSoft Json.Net,我可以更新/添加/删除条目,除非使用以下内容。
这是 json:
string remoteJson = @"{
player: 'MyName',
score: 1000,
lastLogin : '12/20/20154:50:30AM'
}";
然后它被传递给它来更新m_jsonObject:
public bool SetUserPrefsFromRemote(string remoteUserPrefs)
{
if (!IsValidJson(remoteUserPrefs))
{
Debug.LogError("[UserPrefs] Invalid Json from remote");
return false;
}
m_jsonObject.RemoveAll();
m_jsonObject = JObject.Parse(remoteUserPrefs);
SaveLocal();
return true;
}
然后调用此方法来检索值,但在 HERE 行失败。
public bool TryGetValue<T>(string key, out T value, T defaultValue)
{
value = defaultValue;
if (string.IsNullOrEmpty(key))
{
return false;
}
if (!IsInit)
{
Debug.LogError("[UserPrefs] Attempt to access UserPrefs while not initialized");
return false;
}
if (m_jsonObject == null)
{
return false;
}
if (m_jsonObject.TryGetValue(key, out JToken jtoken))
{
value = JsonConvert.DeserializeObject<T>(jtoken.ToString()); // HERE
return true;
}
return false;
}
错误:
Unity.Plastic.Newtonsoft.Json.JsonReaderException : Unexpected character encountered while parsing value: M. Path '', line 1, position 1.
调试时,我看不出有什么问题,“MyName”显示正常。使用以下内容逐一添加条目时效果很好:
public void SetValue(string key, object value)
{
if (string.IsNullOrEmpty(key))
{
throw new System.ArgumentNullException("Provided key is null or empty while setting value");
}
m_jsonObject[key] = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
SaveLocal();
}
编辑: 问题仅出现在字符串上,在解析 JObject 之后:
"{\r\n \"player\": \"MyName\",\r\n \"score\": \"1000\",\r\n \"lastLogin\": \"12/20/20154:50:30AM\"\r\n}"
如果我使用 SetValue 那么它会这样:
"{\r\n \"player\": \"\\\"MyName\\\"\",\r\n \"score\": \"1000\",\r\n \"lastLogin\": \"12/20/20154:50:30AM\"\r\n}"
不知何故 SetValue 在字符串值之前和之后添加了那些额外的 \ 并且 DeserializeObject 可以工作。
问题是您实际上将每个值编码为 JSON 字符串!
在将值分配给
JsonConvert.SerializeObject
之前使用 m_jsonObject
基本上存储嵌套的 JSON 编码字符串 - 在 JSON 中。
如果你仔细观察,问题是不是
仅在字符串上,在解析 JObject 之后
即使是 JSON 格式的数字值也是错误的,例如不是是
"score": "1000"
而是
"score": 1000
使其成为数字 (
int
) 字段,而不是编码的 string
。
也许应该是
public void SetValue<T>(string key, T value)
然后
m_jsonObject[key] = (JToken) value;
使用从各种类型到JToken
的
隐式转换。
然后,在读取值时,反之亦然,而不是期望嵌套的 JSON 字符串并使用
value = JsonConvert.DeserializeObject<T>(jtoken.ToString());
它应该是这样的
value = jtoken.ToObject<T>();