0

Guyz

I am trying to parse a JSON string into object. I have the below entity in which I am parsing the JSON string

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

I am using below method to parse the string into object

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

Below is the JSON string which I am trying to parse

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

The below json string is working

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

While parsing I get below error

The data contract type 'GAP.Entities.Room' cannot be deserialized because the member 'RoomImage' is not public. Making the member public will fix this error. Alternatively, you can make it internal, and use the InternalsVisibleToAttribute attribute on your assembly in order to enable serialization of internal members - see documentation for more details. Be aware that doing so has certain security implications.

Note- RoomImage is marked public in the entity class. I get this error only when JSON string contains RoomImage array string otherwise no erro.

Any help is highly appreciated.

Thanks Vinod

vinod8812
  • 645
  • 10
  • 27

3 Answers3

1

You can download and deserialize an JSON using Newtonsoft.

You have to reference the following DLL, and after that you can try this:

List<Room> deserializedObj = (List<Room>)Newtonsoft.Json.JsonConvert.DeserializeObject(responseText, typeof(List<Room>));
roybalderama
  • 1,650
  • 21
  • 38
0

The property RoomImage is public but your class probably isn't.

Make sure the RoomImage class is also marked public. That should solve the problem.

Alternatively use a library like JSON.NET that can do this deserialization without the need for public classes.

Kenneth
  • 28,294
  • 6
  • 61
  • 84
  • I have posted the RoomImage and BaseEntity as well – vinod8812 Apr 26 '13 at 06:43
  • You say: "I get this error only when JSON string contains RoomImage array string otherwise no error". Does that mean that your JSON has a string array for RoomImage? That's not correct, it should have an array of RoomImage – Kenneth Apr 26 '13 at 06:46
  • 1
    Hm, that looks alight. Strangely enough, in theory this should work. – Kenneth Apr 26 '13 at 07:17
  • Yes this is really frustrating another JSON string is working. https://docs.google.com/document/d/1uQNwMmSyEZSolyxUVJl6gXzZPr6aRAf_WAogmUvVqt4/edit?usp=sharing – vinod8812 Apr 26 '13 at 07:21
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/28952/discussion-between-vinod8812-and-kenneth) – vinod8812 Apr 26 '13 at 07:28
0

The problem with your json is that if RoomImage has a single element, your service returns it as an object {} not as an array of objects [{}].

enter image description here

So If you want to use type-safe classes in your code(since dynamically accessing is also possible) you should pre-process your json before deserializing. Below code works (of course, as everybody says, using 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; }
}
I4V
  • 34,891
  • 6
  • 67
  • 79