tags:

views:

183

answers:

3

I have a large object coming back and I only need a fraction of the data. I was looking at the example here. I essentially want to do the same thing except the problem is I would have an array of "error" objects.

So, it would look like this

{
    "short": {
        "original": "http://www.foo.com/",
        "short": "krehqk",
        "error": [
            {
                "code": 0,
                "msg": "No action taken" 
            },
            {
                "code": 0,
                "msg": "No action taken" 
            }
        ] 
    }
}

Is there an easy way to accomplish this using JObject.Parse or maybe even Linq to JSON? Am I better off just using JsonConvert.DeserializeObject and just not including the properties/objects I don't need in the .NET objects I have created?

UPDATE Using the JSON above here is my test...

[TestMethod]
public void ParseStuffTest()
{
    JObject json = JObject.Parse(shortJson);

    Shortie shortie = new Shortie
    {
        Original = (string)json["short"]["original"],
        Short = (string)json["short"]["short"],
        Error = new ShortError
        {
            Code = (int)json["short"]["error"]["code"],
            ErrorMessage = (string)json["short"]["error"]["msg"]
        }
    };
    Assert.IsNotNull(shortie);
}

public class Shortie
{
    [JsonProperty]
    public string Original { get; set; }

    [JsonProperty]
    public string Short { get; set; }

    [JsonProperty]
    public List<ShortError> Error{ get; set; }
}

public class ShortError
{
    [JsonProperty]
    public int Code { get; set; }
    [JsonProperty]
    public string ErrorMessage { get; set; }
}

Here is the error: Cannot implicitly convert type 'Unit_Tests.Test.ShortError' to 'System.Collections.Generic.List'

What am I missing?

A: 

If your target type (that is, the type that this is being deserialized to) has a property called error that is a List<> or array, this will still work. I would avoid Linq in this case as (in my opinion) it adds unnecessary overhead that is completely unnecessary for serialization.

Both the JavaScriptDeserializer (example) and the Json classes are designed specifically for this, so take advantage of those tools.

If you really only want to deserialize part of the object, you can perform some basic string manipulation on your JSON source before deserializing. In the case of your example, search for everything between "error": and it's matching closing ']' and remove it from your JSON string.

David Lively
A: 

Here's what I came up with... I just don't like it because the real object I'm working with is much larger and there are multiple properties with array objects. Is this my only option??? (Besides the obvious JsonConvert.Deserialize)

[TestMethod]
public void ParseStuffTest()
{
    JObject json = JObject.Parse(shortJson);
    var errors = json["short"]["error"].Children().ToList();
    var shortErrors = new List<ShortError>();
    foreach (var error in errors)
    {
        var shortError = new ShortError
                             {
                                 Code = (int)error["code"],
                                 ErrorMessage = (string)error["msg"]
                             };
        shortErrors.Add(shortError);
    }
    var shortie = new Shortie
    {
        Original = (string)json["short"]["original"],
        Short = (string)json["short"]["short"],
        Error = shortErrors
    };
    Assert.IsNotNull(shortie);
    Assert.AreEqual(2, shortie.Error.Count);
}
Jeepasaurus
A: 

A co-worker just stopped by and showed me exactly what I wanted to do using Linq to JSON...

[TestMethod]
public void ParseStuffTest()
{
    JObject json = JObject.Parse(shortJson);
    var shortie = new Shortie
    {
        Original = (string)json["short"]["original"],
        Short = (string)json["short"]["short"],
        Error = json["short"]["error"].ToList().Select(
            c => new ShortError { Code = (int)c["code"], ErrorMessage = (string)c["msg"] }).ToList()
    };
    Assert.IsNotNull(shortie);
    Assert.AreEqual(2, shortie.Error.Count);
}

Nothing to it. :-)

Jeepasaurus