无法将JSON字符串反序列化为对象

时间:2013-04-26 06:22:46

标签: c# .net json deserialization json2csharp

Guyz

我正在尝试将JSON字符串解析为对象。我有下面的实体,我正在解析JSON字符串

 public class Room : BaseEntity
{
    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public string RoomListEmailAddress { get; set; }
    public string MinimumXCoordinateInMap { get; set; }
    public string MinimumYCoordinateInMap { get; set; }
    public string MaximumXCoordinateInMap { get; set; }
    public string MaximumYCoordinateInMap { get; set; }
    public string RoomCapacity { get; set; }
    public List<RoomImage> RoomImage { get; set; }
    public string FloorName { get; set; }
    public string CreatedDate { get; set; }
    public string CreatedId { get; set; }
    public string LastUpdatedDate { get; set; }
    public string LastUpdatedId { get; set; }
    public InternalOnly InternalOnly { get; set; }
    //public List<Equipment> Equipment { get; set; }


    public override string ToString()
    {

        return this.Name;
    }
}


public class RoomImage : BaseEntity
    {
        public string ImagePath { get; set; }
        public string ImageType { get; set; }
        public string CreatedDate { get; set; }
        public string CreatedId { get; set; }
        public string LastUpdatedDate { get; set; }
        public string LastUpdatedId { get; set; }
        public InternalOnly InternalOnly { get; set; }
    }
  public class InternalOnly : BaseEntity
    {
        public string RoomId { get; set; }
        public string FloorId { get; set; }
    }
 public class BaseEntity
    {
    }

我使用下面的方法将字符串解析为对象

 public static T ParseObjectToJSON<T>(string responseText)
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
        using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(responseText)))
        {
            var rootObject = serializer.ReadObject(stream);
            //return Convert.ChangeType(rootObject,typeof(T),System.Globalization.CultureInfo.CurrentCulture.TextInfo);
            return (T)rootObject;
        }
    } 

下面是我试图解析的JSON字符串

https://docs.google.com/document/d/1k81M_UxIrXpHUPQNDUCHDfNw1wY7LM4mAaXjwpYMshk/edit?usp=sharing

以下json字符串正在运行

https://docs.google.com/document/d/1uQNwMmSyEZSolyxUVJl6gXzZPr6aRAf_WAogmUvVqt4/edit?usp=sharing

解析时我得到以下错误

无法对数据协定类型“GAP.Entities.Room”进行反序列化,因为成员“RoomImage”不是公共的。将该成员公开将修复此错误。或者,您可以将其设置为内部,并使用程序集上的InternalsVisibleToAttribute属性以启用内部成员的序列化 - 有关更多详细信息,请参阅文档。请注意,这样做会产生一定的安全隐患。

注意 - RoomImage在实体类中标记为public。只有当JSON字符串包含RoomImage数组字符串时才会出现此错误,否则不会出错。

非常感谢任何帮助。

由于 维诺德

3 个答案:

答案 0 :(得分:1)

您可以使用Newtonsoft download和反序列化JSON。

您必须引用以下DLL,之后您可以尝试:

List<Room> deserializedObj = (List<Room>)Newtonsoft.Json.JsonConvert.DeserializeObject(responseText, typeof(List<Room>));

答案 1 :(得分:0)

属性RoomImage是公开的,但您的课程可能不是。

确保RoomImage类也标记为public。这应该可以解决问题。

或者使用类似JSON.NET的库,可以在不需要公共类的情况下进行反序列化。

答案 2 :(得分:0)

你的json存在的问题是,如果RoomImage有一个单独的元素,你的服务将它作为一个对象{}而不是一个对象数组[{}]返回。

enter image description here

因此,如果要在代码中使用类型安全的类(因为也可以动态访问),则应在反序列化之前预处理json。下面的代码工作(当然,正如所有人所说,使用Json.Net

string json = your__json__string

//PreProcess
var jobj = JObject.Parse(json);
foreach (var j in jobj["ObjectList"])
{
    if (!(j["RoomImage"] is JArray))
    {
        j["RoomImage"] = new JArray(j["RoomImage"]);
    }
}

var obj = JsonConvert.DeserializeObject<RootObject>(jobj.ToString());

public class InternalOnly
{
    public string RoomId { get; set; }
    public string FloorId { get; set; }
}

public class RoomImage
{
    public string ImagePath { get; set; }
    public string ImageType { get; set; }
    public string CreatedDate { get; set; }
    public string CreatedId { get; set; }
    public string LastUpdateDate { get; set; }
    public string LastUpdateId { get; set; }
}

public class ObjectList
{
    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public string RoomListEmailAddress { get; set; }
    public string MinimumXCoordinateInMap { get; set; }
    public string MinimumYCoordinateInMap { get; set; }
    public string MaximumXCoordinateInMap { get; set; }
    public string MaximumYCoordinateInMap { get; set; }
    public string RoomCapacity { get; set; }
    public RoomImage[] RoomImage { get; set; }
    public string FloorName { get; set; }
    public string CreatedDate { get; set; }
    public string CreatedId { get; set; }
    public string LastUpdatedDate { get; set; }
    public string LastUpdatedId { get; set; }
    public string IsRestrictedRoom { get; set; }
    public InternalOnly InternalOnly { get; set; }
    public object Equipment { get; set; }
}

public class RootObject
{
    public List<ObjectList> ObjectList { get; set; }
}