C# Windows Phone如何使用json.NET将json响应与变量名绑定?
我在反序列化此JSON响应时遇到问题C# Windows Phone如何使用json.NET将json响应与变量名绑定?,c#,silverlight,windows-phone-7,json.net,C#,Silverlight,Windows Phone 7,Json.net,我在反序列化此JSON响应时遇到问题 { "posts": { "Pippo": { "text": "text1", "link": "link1" }, "Pluto": { "text": "text2", "link": "link2" } } } 我用的是这个模型 public class postModel { public string text { get; set; } p
{
"posts": {
"Pippo": {
"text": "text1",
"link": "link1"
},
"Pluto": {
"text": "text2",
"link": "link2"
}
}
}
我用的是这个模型
public class postModel
{
public string text { get; set; }
public string link { get; set; }
}
public class postFields
{
public postModel post { get; set; }
}
public class RootObject
{
public Dictionary<string, postFields> posts { get; set; }
}
然后我得到了NullReferenceException,因为JSON属性的名称不是“post”,而是Pippo、Pluto等
有人能帮我吗?这个json是不可解析的,因为它不能用这样的“动态”键而不是键值对转换成任何类型。你应该使用的是 快速样本:
JObject j = JObject.Parse(json);
var lst = j["posts"][0].Select(jp => ((JProperty)jp).Name).ToList();
项目中需要以下类:
namespace Newtonsoft.Json
{
public class DictionaryConverter<tKey, tValue>: JsonConverter
{
public override bool CanRead { get { return true; } }
public override bool CanWrite { get { return true; } }
public override bool CanConvert( Type objectType )
{
if( !objectType.IsGenericType )
return false;
if( objectType.GetGenericTypeDefinition() != typeof( Dictionary<,> ) )
return false;
Type[] argTypes = objectType.GetGenericArguments();
if( argTypes.Length != 2 || argTypes[ 0 ] != typeof( tKey ) || argTypes[ 1 ] != typeof( tValue ) )
return false;
return true;
}
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
{
do
{
if( JsonToken.StartObject != reader.TokenType )
break;
Dictionary<tKey, tValue> res = new Dictionary<tKey, tValue>();
while( reader.Read() )
{
if( JsonToken.EndObject == reader.TokenType )
return res;
if( JsonToken.PropertyName == reader.TokenType )
{
tKey key = (tKey)Convert.ChangeType( reader.Value, typeof( tKey ), null );
if( !reader.Read() )
break;
tValue val = serializer.Deserialize<tValue>( reader );
res[ key ] = val;
}
}
}
while( false );
throw new Exception( "unexpected JSON" );
}
public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer )
{
if( null == value )
return;
Dictionary<tKey, tValue> src = value as Dictionary<tKey, tValue>;
if( null == src )
throw new Exception( "Expected Dictionary<{0}, {1}>".FormatWith( typeof( tKey ).Name, typeof( tValue ).Name ) );
writer.WriteStartObject();
foreach (var kvp in src)
{
string strKey = (string)Convert.ChangeType( kvp.Key, typeof( string ), null );
writer.WritePropertyName( strKey );
serializer.Serialize( writer, kvp.Value );
}
writer.WriteEndObject();
}
}
}
感谢你们两位;我这样解决:
var main = JObject.Parse(json);
foreach (var mainRoute in main.Properties()) // this is "posts"
{
foreach (var subRoute in mainRoute.Values<JObject>().SelectMany(x => x.Properties())) // this is "Pippo", "Pluto"
{
var deserialized = JsonConvert.DeserializeObject<postModel>(subRoute.Value.ToString());
new postModel
{
text = deserialized.text,
link = deserialized.link
};
}
}
var main=JObject.Parse(json);
foreach(main.Properties()中的var mainRoute)/这是“posts”
{
foreach(mainRoute.Values()中的var子例程。SelectMany(x=>x.Properties())//这是“Pippo”,“Pluto”
{
var deserialized=JsonConvert.DeserializeObject(subcute.Value.ToString());
新的后模型
{
text=反序列化的.text,
link=反序列化的.link
};
}
}
很抱歉,我无法实现此功能,请发布一个带有postModel对象创建的示例代码。我已编辑了此示例,很抱歉,之前的示例错误。通过这种方式,您可以获得所有属性名,然后通过名称访问该jobject。如果你想要详细的教程,我建议你用谷歌搜索如何使用jobject
namespace Newtonsoft.Json
{
public class DictionaryConverter<tKey, tValue>: JsonConverter
{
public override bool CanRead { get { return true; } }
public override bool CanWrite { get { return true; } }
public override bool CanConvert( Type objectType )
{
if( !objectType.IsGenericType )
return false;
if( objectType.GetGenericTypeDefinition() != typeof( Dictionary<,> ) )
return false;
Type[] argTypes = objectType.GetGenericArguments();
if( argTypes.Length != 2 || argTypes[ 0 ] != typeof( tKey ) || argTypes[ 1 ] != typeof( tValue ) )
return false;
return true;
}
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
{
do
{
if( JsonToken.StartObject != reader.TokenType )
break;
Dictionary<tKey, tValue> res = new Dictionary<tKey, tValue>();
while( reader.Read() )
{
if( JsonToken.EndObject == reader.TokenType )
return res;
if( JsonToken.PropertyName == reader.TokenType )
{
tKey key = (tKey)Convert.ChangeType( reader.Value, typeof( tKey ), null );
if( !reader.Read() )
break;
tValue val = serializer.Deserialize<tValue>( reader );
res[ key ] = val;
}
}
}
while( false );
throw new Exception( "unexpected JSON" );
}
public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer )
{
if( null == value )
return;
Dictionary<tKey, tValue> src = value as Dictionary<tKey, tValue>;
if( null == src )
throw new Exception( "Expected Dictionary<{0}, {1}>".FormatWith( typeof( tKey ).Name, typeof( tValue ).Name ) );
writer.WriteStartObject();
foreach (var kvp in src)
{
string strKey = (string)Convert.ChangeType( kvp.Key, typeof( string ), null );
writer.WritePropertyName( strKey );
serializer.Serialize( writer, kvp.Value );
}
writer.WriteEndObject();
}
}
}
public class RootObject
{
[ JsonProperty, JsonConverter( typeof( DictionaryConverter<string, postModel> ) ) ]
public Dictionary<string, postModel> posts;
}
public static class SharedUtils
{
public static string FormatWith( this string format, params object[] args )
{
if( format == null )
throw new ArgumentNullException( "format" );
return String.Format( format, args );
}
}
var main = JObject.Parse(json);
foreach (var mainRoute in main.Properties()) // this is "posts"
{
foreach (var subRoute in mainRoute.Values<JObject>().SelectMany(x => x.Properties())) // this is "Pippo", "Pluto"
{
var deserialized = JsonConvert.DeserializeObject<postModel>(subRoute.Value.ToString());
new postModel
{
text = deserialized.text,
link = deserialized.link
};
}
}