Uza*_*jid 64 c# json.net windows-phone-7 restsharp
TL; DR版本
我有一个类型的对象JToken
(但也可以是一个string
),我需要将它转换为type
变量中包含的类型:
Type type = typeof(DateTime); /* can be any other Type like string, ulong etc */
var obj = jsonObject["date_joined"]; /* contains 2012-08-13T06:01:23Z+05:00 */
var result = Some_Way_To_Convert(type, obj);
Run Code Online (Sandbox Code Playgroud)
上面result
应该是一个DateTime对象,其值为date_joined
.
全文
我在Windows Phone项目中使用RestSharp和Json.NET,并且在尝试从REST API反序列化JSON响应时遇到困难.
我实际上要完成的是编写一个通用方法,可以轻松地将我的JSON响应映射到我的CLR实体,就像你已经可以使用RestSharp一样.唯一的问题是默认的RestSharp实现对我不起作用,并且它无法成功解析JSON,因为响应并不总是返回所有属性(我不返回null
来自REST服务器的字段).
这就是为什么我决定使用Newtonsoft的Json.NET,因为它有一个更强大的Json反序列化引擎.不幸的是,它不支持像RestSharp这样的模糊属性/字段名称(或者我还没有找到),所以当我使用像say这样的东西时,它也不能正确地映射到我的CLR实体JsonConvert.DeserializeObject<User>(response.Content)
.
这是我的Json的样子(实际上是一个例子):
{
"id" : 77239923,
"username" : "UzEE",
"email" : "uzee@email.net",
"name" : "Uzair Sajid",
"twitter_screen_name" : "UzEE",
"join_date" : "2012-08-13T05:30:23Z05+00",
"timezone" : 5.5,
"access_token" : {
"token" : "nkjanIUI8983nkSj)*#)(kjb@K",
"scope" : [ "read", "write", "bake pies" ],
"expires" : 57723
},
"friends" : [{
"id" : 2347484",
"name" : "Bruce Wayne"
},
{
"id" : 996236,
"name" : "Clark Kent"
}]
}
Run Code Online (Sandbox Code Playgroud)
这是我的CLR实体的一个例子:
class AccessToken
{
public string Token { get; set; }
public int Expires { get; set; }
public string[] Scope { get; set; }
public string Secret { get; set; } /* may not always be returned */
}
class User
{
public ulong Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string TwitterScreenName { get; set; }
public DateTime JoinDate { get; set; }
public float Timezone { get; set; }
public bool IsOnline { get; set; } /* another field that might be blank e.g. */
public AccessToken AccessToken { get; set; }
public List<User> Friends { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想要的是一种将上述JSON解析为给定CLR对象的简单方法.我看了看周围的RestSharp源代码,并已经看到了JsonDeserializer
代码,我已经能够编写一个通用的扩展方法DeserializeResponse<T>
上JObject
应该返回类型的对象T
.预期用途是这样的:
var user = JObject.Parse(response.Content).DeserializeResponse<User>();
Run Code Online (Sandbox Code Playgroud)
上面的方法应该将给定的Json Response解析为User实体对象.这是我在DeserializeResponse<User>
扩展方法中所做的实际代码片段(基于RestSharp代码):
public static T DeserializeResponse<T>(this JObject obj) where T : new()
{
T result = new T();
var props = typeof(T).GetProperties().Where(p => p.CanWrite).ToList();
var objectDictionary = obj as IDictionary<string, JToken>;
foreach (var prop in props)
{
var name = prop.Name.GetNameVariants(CultureInfo.CurrentCulture).FirstOrDefault(n => objectDictionary.ContainsKey(n));
var value = name != null ? obj[name] : null;
if (value == null) continue;
var type = prop.PropertyType;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = type.GetGenericArguments()[0];
}
// This is a problem. I need a way to convert JToken value into an object of Type type
prop.SetValue(result, ConvertValue(type, value), null);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我猜测转换应该是一个非常简单的事情,因为它是一项微不足道的任务.但是我一直在寻找相当长的一段时间,但仍然没有找到通过Json.NET做到这一点的方法(说实话,文档虽然有点理解,但缺少一些例子).
真的很感激任何帮助.
Sof*_*ion 120
现在有一个ToObject方法.
var obj = jsonObject["date_joined"];
var result = obj.ToObject<DateTime>();
Run Code Online (Sandbox Code Playgroud)
它也适用于任何复杂类型,并遵守JsonPropertyAttribute规则
var result = obj.ToObject<MyClass>();
public class MyClass
{
[JsonProperty("date_field")]
public DateTime MyDate {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
L.B*_*L.B 23
System.Convert.ChangeType(jtoken.ToString(), targetType);
Run Code Online (Sandbox Code Playgroud)
要么
JsonConvert.DeserializeObject(jtoken.ToString(), targetType);
Run Code Online (Sandbox Code Playgroud)
- 编辑 -
Uzair,这是一个完整的例子,只是为了告诉你他们的工作
string json = @"{
""id"" : 77239923,
""username"" : ""UzEE"",
""email"" : ""uzee@email.net"",
""name"" : ""Uzair Sajid"",
""twitter_screen_name"" : ""UzEE"",
""join_date"" : ""2012-08-13T05:30:23Z05+00"",
""timezone"" : 5.5,
""access_token"" : {
""token"" : ""nkjanIUI8983nkSj)*#)(kjb@K"",
""scope"" : [ ""read"", ""write"", ""bake pies"" ],
""expires"" : 57723
},
""friends"" : [{
""id"" : 2347484,
""name"" : ""Bruce Wayne""
},
{
""id"" : 996236,
""name"" : ""Clark Kent""
}]
}";
var obj = (JObject)JsonConvert.DeserializeObject(json);
Type type = typeof(int);
var i1 = System.Convert.ChangeType(obj["id"].ToString(), type);
var i2 = JsonConvert.DeserializeObject(obj["id"].ToString(), type);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
121884 次 |
最近记录: |