2

I wrote some code and it works, but I double-convert json twice, and it's a little embarrassing.

I get data that is wrapped in a "d" object, how can I get its contents right away

Here's the Json that I get:

{
    "d": [
    {
        "__type": "MdoCommonWs.WsStructures.WsWmsLookupResult",
        "CallResult": {
            "Id": 0,
            "Data": null,
            "ErrorId": 0,
            "ErrorDescription": null
        },
        "Article": {
            "Id": "001",
            "Description": "ANKER M12 MECHANISCH",
            "Unit": "pieces",
            "UnitPrice": 7,
            "MinStock": 0,
            "MaxStock": 0,
            "Info": "ANKER MECHANISCH M12",
            "Photo": [],
            "PhotoUrl": "",
            "WeightUnit": "kg",
            "Weight": 0.05,
            "CountStock": 0
        },
        "Locations": [
            {
                "LocationId": "00.00.AA.01.01.01.02",
                "Type": 0,
                "IsBlocked": false,
                "ArticleId": "001",
                "Stock": 2,
                "TotalStock": 2,
                "LastActionDate": "/Date(1480334382093)/",
                "LastInventoryDate": "/Date(1480334319527)/"
            }
        ],
    }],
}

Here is my code to convert:

var rootJObject = JObject.Parse(stringSerialized);
var serialize = rootJObject["d"].ToString();

return JsonConvert.DeserializeObject<TResult>(serialize);

How can I do this more efficiently?

4
  • 1
    Can't you just return rootObject["d"]? It's already deserialized. Commented Sep 7, 2018 at 10:39
  • 1
    That would return a JObject @PalleDue, I'm guessing OP wants it strongly typed TResult Commented Sep 7, 2018 at 10:41
  • How about creating an object around d ? Commented Sep 7, 2018 at 10:53
  • @Liam: Yes, of course. My bad. Commented Sep 7, 2018 at 13:25

2 Answers 2

2

You could declare an object around your d member:

public class Root<T>
{
    [JsonProperty("d")]
    public T Data { get; set; }
}

Then simply:

JsonConvert.DeserializeObject<Root<TResult>>(json).Data;

Another method is to deserialize into a JObject:

public class Root
{
    [JsonProperty("d")]
    public JObject Data { get; set; }
}

JsonConvert.DeserializeObject<Root>(json).Data.ToObject<TResult>();
Sign up to request clarification or add additional context in comments.

1 Comment

Oh, yeah, this is the best i think
2

There are a number of ways to do this, here's what I use:

public async Task<IEnumerable<TResult>> ParseJson<TResult>(string stringSerialized)
{
  using (StringReader streamReader = new StringReader(stringSerialized))
  using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
  {
            JObject parsedData = await JObject.LoadAsync(jsonTextReader);
            if (parsedData == null || parsedData["d"] == null || parsedData["d"].Children().Any() == false)
                return new List<T>();
            else
                return parsedData["d"].Children().Select(s => s.ToObject<TResult>());
   }
 }

If stringSerialized is coming from a Stream you can make this more efficient but just processing that stream directly, this saves you turning the stream into a string to turn the string into an object:

   public async Task<IEnumerable<TResult>> ParseStream<TResult>(Stream contentStream)
    {

        using (StreamReader streamReader = new StreamReader(contentStream))
        using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
        {
            jsonTextReader.DateFormatString = _dateFormatString;
            JObject parsedData = await JObject.LoadAsync(jsonTextReader);
            if (parsedData == null || parsedData["d"] == null || parsedData["d"].Children().Any() == false)
                return new List<TResult>();
            else
                return parsedData["d"].Children().Select(s => s.ToObject<TResult>());
        }
    }

Be sure to dispose and clean up Stream contentStream correctly using using.

For a non async version just replace:

JObject parsedData = await JObject.LoadAsync(jsonTextReader);

with

JObject parsedData = JObject.Load(jsonTextReader);

and change the signature to:

public IEnumerable<TResult> ParseJson<TResult>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.