我试图从C#visual studio 2010中的Web服务解析一些结果,这些结果是以JSON形式返回的,但是名为data的字段有时是字符串,有时是对象。我不确定如何获得数据合同来处理这个问题。当它运行反序列化时,它只返回所有内容的null结果。如果我尝试的网络请求没有任何profile_results,那么就可以了。
JSON看起来像这样
{
"ListSingleOrganization": {
"id": 86270,
"short_name": "someshort name",
"long_name": "Long name",
"created_at": "2014-05-02T14:21:06Z",
"is_disabled": false,
"description": "Verbose description",
"renewed_at": "2014-05-02T14:21:07Z",
"alternate_id": null,
"website_url": "http://www.url.com",
"member_count": 50,
"pic_url": "https://www.somepicture.com/1.jpg",
"umbrella_id": 36016,
"keywords": "Fraternity, Leadership, Human Service, Scholarship",
"category": {
"id": 53282,
"name": "Fraternities"
},
"profile_responses": [
{
"element": {
"id": 51350,
"name": "Group Email Address",
"type": "Email"
},
"data": "groupsemail@gmail.com"
},
{
"element": {
"id": 1239634,
"name": "Please list your organization's Twitter handle so we may follow you with our office's account. (@something)",
"type": "TextField"
},
"data": "@handle"
},
{
"element": {
"id": 1192652,
"name": "Is this a new organization?",
"type": "Radio"
},
"data": {
"id": 2003570,
"name": "No"
}
}
]
}
}
差异是基于元素类型,但我不知道如何用它们具有相同的名称来解释它。
现在我有
[DataContract]
class ListSingleOrganization
{
//other members
[DataMember(Name = "profile_responses")]
public List<profile_responses> profile_responses { get; set; }
}
[DataContract]
class profile_responses
{
[DataMember(Name = "element")]
public element element { get; set; }
[DataMember(Name="data")]
public data data {get; set; }
}
[DataContract]
class element
{
[DataMember(Name = "id")]
public int id { get; set; }
[DataMember(Name = "name")]
public string name { get; set; }
[DataMember(Name = "type")]
public string type { get; set; }
}
[DataContract]
class data
{
[DataMember(Order=1)]
public string raw { get; set; }
[DataMember(Name = "file_name")]
public string file_name { get; set; }
[DataMember(Name = "url")]
public string url { get; set; }
[DataMember(Name = "id")]
public int id { get; set; }
[DataMember(Name = "name")]
public string name { get; set; }
}
答案 0 :(得分:1)
您可以创建自定义格式化程序来读取属性,检查它是否为字符串。如果它是一个字符串,则创建数据类的新实例,并将其中一个属性设置为字符串值。否则,将其反序列化为您的数据对象。
public class JsonDataConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(data));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
data returnVal = null;
// You may need to debug this and see which token type is being returned
// per data element and adjust, but the principle stands.
if (reader.TokenType == JsonToken.String)
{
returnVal = new data();
returnVal.raw = reader.ReadAsString();
}
else
{
returnVal = serializer.Deserialize<data>(reader);
}
return returnVal;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// Assuming you only need to deserialize
throw new NotImplementedException();
}
}
将JsonConverter与您的财产关联:
[DataMember(Name = "data")]
[JsonConverter(typeof(JsonDataConverter))]
public data data { get; set; }
编辑:(回答跟进问题) 在一个单独的单元测试中进行设置,并在尝试将其放入SSIS包之前先让它在那里工作。如果您使用DataContractSerializer,则不会调用JsonDataConverter类。您想使用Json.NET反序列化:
using Newtonsoft.Json;
. . .
var orgList JsonConvert.DeserializeObject<ListSingleOrganization>(webServiceResultString);
答案 1 :(得分:0)
无法使用DataContract Serializes来处理这些违规行为,所以我选择了动态对象路线,并且运行良好。