C# Datacontract对象和字符串

C# Datacontract对象和字符串,c#,json,serialization,datacontract,C#,Json,Serialization,Datacontract,我试图解析一些来自C#visual studio 2010中的web服务的结果,这些结果将以JSON格式返回,但名为data的字段有时是字符串,有时是对象。我不知道如何让数据合同来处理这个问题。当它运行反序列化时,它只会为所有内容返回一个空结果。如果我尝试一个没有任何配置文件结果的web请求,那么它可以正常工作 JSON看起来像这样 { "ListSingleOrganization": { "id": 86270, "short_name": "someshort name", "long_n

我试图解析一些来自C#visual studio 2010中的web服务的结果,这些结果将以JSON格式返回,但名为data的字段有时是字符串,有时是对象。我不知道如何让数据合同来处理这个问题。当它运行反序列化时,它只会为所有内容返回一个空结果。如果我尝试一个没有任何配置文件结果的web请求,那么它可以正常工作

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; }

}
[DataContract]
类列表组织
{
//其他成员
[DataMember(Name=“profile_responses”)]
公共列表配置文件\u响应{get;set;}
}
[数据合同]
课程简介及回应
{
[DataMember(Name=“element”)]
公共元素元素{get;set;}
[DataMember(Name=“data”)]
公共数据数据{get;set;}
}
[数据合同]
类元素
{
[数据成员(Name=“id”)]
公共int id{get;set;}
[数据成员(Name=“Name”)]
公共字符串名称{get;set;}
[DataMember(Name=“type”)]
公共字符串类型{get;set;}
}
[数据合同]
类数据
{
[数据成员(顺序=1)]
公共字符串原始{get;set;}
[DataMember(Name=“file_Name”)]
公共字符串文件名{get;set;}
[DataMember(Name=“url”)]
公共字符串url{get;set;}
[数据成员(Name=“id”)]
公共int id{get;set;}
[数据成员(Name=“Name”)]
公共字符串名称{get;set;}
}

您可以创建自定义格式化程序来读取属性,检查它是否为字符串。如果是字符串,则创建数据类的新实例,并将其中一个属性设置为字符串值。否则,将其反序列化为您的数据对象

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();
    }
}
编辑:(回答后续问题)
在一个独立的单元测试中设置它,并在尝试将其放入SSIS包之前首先让它在那里工作。如果您使用的是DataContractSerializer,则不会调用JsonDataConverter类。要使用Json.NET反序列化:

using Newtonsoft.Json;

. . .

var orgList JsonConvert.DeserializeObject<ListSingleOrganization>(webServiceResultString);
使用Newtonsoft.Json;
. . .
var orgList JsonConvert.DeserializeObject(webServiceResultString);

无法让DataContract序列化处理这些异常情况,因此我采用了动态对象路径,这就成功了


您可以随时将其作为对象接收,然后您可以使用自定义映射器映射该对象。我正在使用DataContractJsonSerialize。我认为您的解决方案可能会起作用。但是我认为我不能使用JSON.net。我试图在SSIS中实现这个解决方案,我可以在脚本编辑器中构建它,但是当脚本化组件在集成项目中构建时,它会抛出一个丢失的文件异常,并且找不到第三方dll。因此,我将JSON.net添加到GAC中,这样它就可以工作了,但是当我运行代码时,它仍然不匹配,我只得到一个空值结果。可能是因为我使用的是DataContractJsonSerializer。请在一个独立的单元测试中设置它,并在尝试将其放入SSIS包之前先让它在那里工作。如果您使用的是DataContractSerializer,则不会调用JsonDataConverter类。使用Newtonsoft.Json。var orgList JsonConvert.DeserializeObject(webServiceResultString);
using Newtonsoft.Json;

. . .

var orgList JsonConvert.DeserializeObject<ListSingleOrganization>(webServiceResultString);