0

I'm trying to develop a solution that comprises of a UWP front-end which gets data from an Azure hosted asp.net ApiController, and ideally I'd like to send the data in JSON format.

The architecture is fairly simple, I have a set of POCO's (non-complex classes as my DTO's).

Because the solution has two parts, one of which is UWP, I've made two sets of the POCO's, as I haven't experimented with making make 'Portable' class libraries. From memory I've used this approach before without issue but that was serializing and deserializing using (not sure what the right phrase is) "native"/binary serialization rather than JSON.

Serializing the data in the controller is no trouble:

using using System.Web.Script.Serialization;

array = new CurrentSpendInfo[someCostCodes.Count()];
foreach (CostCodeInfo c in someCostCodes)
{
  info = new CurrentSpendInfo();
  array[i] = info;
  info.CostCodeName = c.CostCodeName;
  info.AnnualBudget = c.Budget;
  ...
}
return new JavaScriptSerializer().Serialize(array);

Which creates the JSON:

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
    [{"CostCodeName":"Food","AnnualBudget":20000,"AnnualSpentToDate":0,"AnnualRemainigBalance":20000,"AnnualSpendAsPercentage":0,"EstMonthlyBudget":0,"EstMonthlyBudgetToDate":0,"TotalVariance":0,"ActualAverageMonthlySpend":NaN,"ActualMonthlySpendToDateAsPercentage":NaN,"TransactionCount":0,"Avg":0,"Min":0,"Max":0,"CostCodeUID":"255697c8-b05e-436b-9b37-09593348bb32"},
{"CostCodeName":"Travel","AnnualBudget":6000,"AnnualSpentToDate":0,"AnnualRemainigBalance":6000,"AnnualSpendAsPercentage":0,"EstMonthlyBudget":0,"EstMonthlyBudgetToDate":0,"TotalVariance":0,"ActualAverageMonthlySpend":NaN,"ActualMonthlySpendToDateAsPercentage":NaN,"TransactionCount":0,"Avg":0,"Min":0,"Max":0,"CostCodeUID":"75b66211-0f58-491e-b119-d4cb212ec9fa"},
{"CostCodeName":"Total","AnnualBudget":26000,"AnnualSpentToDate":0,"AnnualRemainigBalance":26000,"AnnualSpendAsPercentage":0,"EstMonthlyBudget":0,"EstMonthlyBudgetToDate":0,"TotalVariance":0,"ActualAverageMonthlySpend":NaN,"ActualMonthlySpendToDateAsPercentage":0,"TransactionCount":0,"Avg":0,"Min":0,"Max":0,"CostCodeUID":""}]
    </string>

The problem is that in UWP land the array isn't being deserialized, it fails on the last line shown below:

using Windows.Web.Http;
using Windows.Data.Json;

HttpResponseMessage rspn = await _HttpClient.GetAsync(geturi);
string response = await rspn.Content.ReadAsStringAsync();
JsonArray root = JsonValue.Parse(response).GetArray();

WinRT information: This is not an array value. Use ValueType property to get the type.

Additional information: A method was called at an unexpected time.

This is not an array value. Use ValueType property to get the type.

If there is a handler for this exception, the program may be safely continued.

How do I get around this?

I notice the serializer talks about value types - is this related to the fact that my classes are reference types rather than value types?

Should I be using different JSON libraries to do the serialization? That's not a trivial thing as far as I can see - using Newtonsoft would be ideal, but there's compatibility issues between that and recent versions of the libraries underneath UWP.

Or do I have to fall back on XML?

Adrian K
  • 9,880
  • 3
  • 33
  • 59
  • Can use newtoSoft json ? It have attribute that can set the UWP have Asp can use the rule. – lindexi Apr 14 '17 at 01:11
  • Your "JSON" is actually an XML serialized string literal containing JSON. 1) Rather than serializing yourself, let the framework do it, otherwise you get double-serialized responses as in [this question](https://stackoverflow.com/q/25559179/3744182). 2) To get your web API to return JSON, see maybe https://stackoverflow.com/q/12629144/3744182 or https://stackoverflow.com/q/9847564/3744182 – dbc Apr 14 '17 at 01:41
  • The XML is the envelope, it's the JSON payload that I want to deserialze. – Adrian K Apr 14 '17 at 05:43

1 Answers1

0

This worked. The issues I had were (1) getting misled by the Visual Studio visualiser (i.e. when looking at the response string (JSON) at runtime), (2) not trimming off the surrounding double quotes, (3) getting rid of unwanted backslashes and (4) removing any stray line breaks:

    HttpResponseMessage rspn = await _HttpClient.GetAsync(geturi);
    string response = await rspn.Content.ReadAsStringAsync();

    response = response.Replace(Environment.NewLine, string.Empty);
    response = response.Replace(@"\", string.Empty);
    response = response.Substring(1, response.Length - 2);

    JsonArray root = JsonValue.Parse(response).GetArray();

I might need to revisit the removal of backslashes in case there's ever any legitimate ones in the content.

Adrian K
  • 9,880
  • 3
  • 33
  • 59