Problem with string (string contains brace characters and a plus sign) - c#

I have a problem with regex. The variable media.Value may contain the characters "() +" which causes an error in the regex and prevents it from working.
My code
Match renderMatch = Regex.Match(mediaMatch.Groups[0].Value, "(?<=\"name\":\"" + media.Value + "\",\"render\":).*?(?=,)");
Match mutedMatch = Regex.Match(mediaMatch.Groups[0].Value, "(?<=\"muted\":).*?(?=,\"name\":\"" + media.Value + "\")");
json I work with
[{"alignment":5,"cx":844.0,"cy":264.0,"id":4,"locked":false,"muted":false,"name":"Text (GDI +)","render":true,"source_cx":844,"source_cy":264,"type":"text_gdiplus_v2","volume":1.0,"x":549.0,"y":383.0},{"alignment":5,"cx":1920.0,"cy":1080.0,"id":3,"locked":false,"muted":false,"name":"Color","render":true,"source_cx":1920,"source_cy":1080,"type":"color_source_v3","volume":1.0,"x":0.0,"y":0.0}]
As long as there are no "()" in the name field everything works. For example:
Working
"muted":false,"name":"Color","render":true
Not working
"muted":false,"name":"Text (GDI +)","render":true
The question is.
Is there any regex option that would ignore the () in string, or how else could I get an output like this:
"Text \(GDI \+\)"

You can deserialize your JSON string to strongly typed models and then gather your required fields
An example with your JSON string is: https://dotnetfiddle.net/cqkOdu
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var myJsonResponse= #"[{'alignment':5,'cx':844.0,'cy':264.0,'id':4,'locked':false,'muted':false,'name':'Text (GDI +)','render':true,'source_cx':844,'source_cy':264,'type':'text_gdiplus_v2','volume':1.0,'x':549.0,'y':383.0},{'alignment':5,'cx':1920.0,'cy':1080.0,'id':3,'locked':false,'muted':false,'name':'Color','render':true,'source_cx':1920,'source_cy':1080,'type':'color_source_v3','volume':1.0,'x':0.0,'y':0.0}]";
List<Root> myDeserializedClass = JsonConvert.DeserializeObject<List<Root>>(myJsonResponse);
foreach(var item in myDeserializedClass)
{
Console.WriteLine(item.name);
}
}
}
public class Root
{
public int alignment { get; set; }
public double cx { get; set; }
public double cy { get; set; }
public int id { get; set; }
public bool locked { get; set; }
public bool muted { get; set; }
public string name { get; set; }
public bool render { get; set; }
public int source_cx { get; set; }
public int source_cy { get; set; }
public string type { get; set; }
public double volume { get; set; }
public double x { get; set; }
public double y { get; set; }
}

Related

Convert to decimal when using CsvHelper

When I try to use CsvHelper to parse the below CSV, I get a "conversion cannot be performed" error (full error is below). It looks like I'm missing something about how to deal with reading values as decimals. Have seen some other answers relating to setting the culture, but that doesn't seem to have helped.
The CSV data is:
Title,Amount,NHS,Reference,GoCardless ID,email,surname,firstname,Full Name,DOB,Age,Right Lens,Left Lens,RightLensMonthlyAmount,LeftLensMonthlyAmount,LensMonthlyAmount,FeeMonthlyAmount,VAT Basis,LensBespokePrice,CareOnly,Notes
Mrs,24.3,N,100247,CUXXX,email#gmail.com,User,Test,Test User,17/09/1957,64,DAILIES® AquaComfort PLUS 30 Pack,DAILIES® AquaComfort PLUS 30 Pack,16.5,16.5,33,6.35,,,,
My class to map this data to properties is:
public class Payer
{
public string Title { get; set; }
public decimal Amount { get; set; }
[BooleanTrueValues("Y")]
[BooleanFalseValues("N")]
public bool NHS { get; set; }
public string Reference { get; set; }
[Name("GoCardless ID")]
public string GoCardless_ID { get; set; }
public string email { get; set; }
public string surname { get; set; }
public string firstname { get; set; }
[Name("Full Name")]
public string Fullname { get; set; }
[Name("DOB")]
public string Dob { get; set; }
public int Age { get; set; }
[Name("Right Lens")]
public string RightLens { get; set; }
[Name("Left Lens")]
public string LeftLens { get; set; }
public decimal RightLensMonthlyAmount { get; set; }
public decimal LeftLensMonthlyAmount { get; set; }
public decimal LensMonthlyAmount { get; set; }
public decimal FeeMonthlyAmount { get; set; }
[Name("VAT Basis")]
public string VATBasis { get; set; }
public decimal LensBespokePrice { get; set; }
[BooleanTrueValues("Y")]
public bool CareOnly { get; set; }
}
My code related to parsing the CSV is:
static void Main(string[] args)
{
var culture = new CultureInfo("en-GB");
var config = new CsvHelper.Configuration.CsvConfiguration(culture);
using (var reader = new StreamReader("test.csv"))
using (var csv = new CsvReader(reader, config))
{
var records = csv.GetRecords<Payer>();
Console.WriteLine("Got records"); //this prints on the console
foreach (var payer in records)
{
Console.WriteLine(payer);
}
}
}
The error only happens with the foreach loop, not the actual GetRecords() method.
Full error:
CsvHelper.TypeConversion.TypeConverterException: "The conversion cannot be performed.\n Text: ''\n MemberType: System.Decimal\n TypeConverter: 'CsvHelper.TypeConversion.DecimalConverter'\nIReader state:\n ColumnCount: 0\n CurrentIndex: 18\n HeaderRecord:\n["Title","Amount","NHS","Reference","GoCardless ID","email","surname","firstname","Full Name","DOB","Age","Right Lens","Left Lens","RightLensMonthlyAmount","LeftLensMonthlyAmount","LensMonthlyAmount","FeeMonthlyAmount","VAT Basis","LensBespokePrice","CareOnly","Notes"]\nIParser state:\n ByteCount: 0\n CharCount: 392\n Row: 2\n RawRow: 2\n Count: 21\n RawRecord:\nMrs,24.3,N,100247,CUXXX,email#gmail.com,User,Test,Test User,17/09/1957,64,DAILIES® AquaComfort PLUS 30 Pack,DAILIES® AquaComfort PLUS 30 Pack,16.5,16.5,33,6.35,,,,\r\n\n"
at CsvHelper.TypeConversion.DefaultTypeConverter.ConvertFromString(String text, IReaderRow row, MemberMapData memberMapData)\n at CsvHelper.TypeConversion.DecimalConverter.ConvertFromString(String text, IReaderRow row, MemberMapData memberMapData)\n at CsvHelper.Expressions.RecordCreator.CreateT\n at CsvHelper.Expressions.RecordManager.CreateT\n at CsvHelper.CsvReader.d__87`1.MoveNext()\n at dd_journal.Program.Main(String[] args) in /Users/abhi/Documents/Practice/dd-journal/Program.cs:22
So the issue is that CSVHelper doesn't understand how to convert an empty field for LensBespokePrice to a decimal value. There are two options you can use here:
Update the CSV file to add a default value to the empty fields (i.e. 0 for LensBespokePrice).
Create a Type Conversion to handle an empty cell to a decimal.
Do you have the ability to modify the CSV file? If so, then #1 works by changing your CSV to be (note the change for LensBespokePrice and CareOnly):
Title,Amount,NHS,Reference,GoCardless ID,email,surname,firstname,Full Name,DOB,Age,Right Lens,Left Lens,RightLensMonthlyAmount,LeftLensMonthlyAmount,LensMonthlyAmount,FeeMonthlyAmount,VAT Basis,LensBespokePrice,CareOnly,Notes
Mrs,24.3,N,100247,CUXXX,email#gmail.com,User,Test,Test User,17/09/1957,64,DAILIES® AquaComfort PLUS 30 Pack,DAILIES® AquaComfort PLUS 30 Pack,16.5,16.5,33,6.35,,0,N,
If not, you'll need a type converter for both the empty decimal and empty boolean. For example, with all your code in a single file, that may look like:
using CsvHelper;
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
using CsvHelper.TypeConversion;
using System;
using System.Globalization;
using System.IO;
using System.Text.Json;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var culture = new CultureInfo("en-GB");
var config = new CsvConfiguration(culture);
using (var reader = new StreamReader("test.csv"))
using (var csv = new CsvReader(reader, config))
{
var records = csv.GetRecords<Payer>();
Console.WriteLine("Got records"); //this prints on the console
foreach (var payer in records)
{
var j = JsonSerializer.Serialize(payer);
Console.WriteLine(j);
}
}
}
}
public class CustomDecimalConverter : DecimalConverter
{
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if(decimal.TryParse(text, out var result))
{
return result;
} else
{
return decimal.Zero;
}
}
}
public class CustomBooleanConverter : BooleanConverter
{
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if (bool.TryParse(text, out var result))
{
return result;
}
else
{
return false;
}
}
}
public class Payer
{
public string Title { get; set; }
public decimal Amount { get; set; }
[BooleanTrueValues("Y")]
[BooleanFalseValues("N")]
public bool NHS { get; set; }
public string Reference { get; set; }
[Name("GoCardless ID")]
public string GoCardless_ID { get; set; }
public string email { get; set; }
public string surname { get; set; }
public string firstname { get; set; }
[Name("Full Name")]
public string Fullname { get; set; }
[Name("DOB")]
public string Dob { get; set; }
public int Age { get; set; }
[Name("Right Lens")]
public string RightLens { get; set; }
[Name("Left Lens")]
public string LeftLens { get; set; }
public decimal RightLensMonthlyAmount { get; set; }
public decimal LeftLensMonthlyAmount { get; set; }
public decimal LensMonthlyAmount { get; set; }
public decimal FeeMonthlyAmount { get; set; }
[Name("VAT Basis")]
public string VATBasis { get; set; }
[TypeConverter(typeof(CustomDecimalConverter))]
public decimal LensBespokePrice { get; set; }
[BooleanTrueValues("Y")]
[BooleanFalseValues("N")]
[TypeConverter(typeof(CustomBooleanConverter))]
public bool CareOnly { get; set; }
}
}
Please note that I added the JsonSerializer.Serialize(payer); in the foreach loop within the Main method so that you can view the JSON result from the console.
I added in two custom converters (CustomBooleanConverter and CustomDecimalConverter). The payer class is then updated to have attributes added to the LensBespokePrice and CareOnly properties. Additionally, you didn't have an attribute on CareOnly for false values and while not required is a good practice.
To clarify why this is happening only in your foreach loop and not var records = csv.GetRecords<Payer>(); is because the values aren't actually converted into your payer class until the records are enumerated.
Payer is a whole class of values. It looks like it is trying to convert when you write to the console. I believe you will need to tell it what part of payer you are wanting to print like:
Console.WriteLine(payer.surname);

Dealing with VarVector<Single> Feature column in ML.NET

I have a tricky model I'm trying to normalize for binary classification. Here's an example of the model structure. I renamed a few things just to simplify.
public class Review
{
public bool Label { get; set; }
public ReviewItem ReviewItem { get; set; }
public List<OtherItem> OtherItems { get; set; }
}
public class ReviewItem
{
public string SomeText { get; set; }
public float SomeNumber { get; set; }
public bool SomeBool { get; set; }
}
public class OtherItem
{
public string SomeDifferentText { get; set; }
public float SomeDifferentNumber { get; set; }
public bool SomeDifferentBool { get; set; }
}
There can be any number of OtherItem in the List. This is what I tried to flatten the model a bit.
public class ReviewMlModel
{
public bool Label { get; set; }
public string ReviewItem_SomeText { get; set; }
public float ReviewItem_SomeNumber { get; set; }
public bool ReviewItem_SomeBool { get; set; }
public string[] OtherItem_SomeDifferentText { get; set; }
public float[] OtherItem_SomeDifferentNumber { get; set; }
public bool[] OtherItem_SomeDifferentBool { get; set; }
}
From there I tried this to normalize it:
var data = mlContext.Data.LoadFromEnumerable(allReviews);
var dataPrepEstimator = mlContext.Transforms.Text.FeaturizeText("ReviewItem_SomeText")
.Append(mlContext.Transforms.Text.FeaturizeText("OtherItem_SomeDifferentText"))
.Append(mlContext.Transforms.Conversion.ConvertType("ReviewItem_SomeBool"))
.Append(mlContext.Transforms.Conversion.ConvertType("OtherItem_SomeDifferentBool"))
.Append(mlContext.Transforms.Concatenate("Features",
"ReviewItem_SomeText", "OtherItem_SomeDifferentText", "ReviewItem_SomeBool",
"OtherItem_SomeDifferentBool", "ReviewItem_SomeNumber", "OtherItem_SomeDifferentNumber"));
var transformedData = dataPrepEstimator.Fit(data).Transform(data);
var model = mlContext.BinaryClassification.Trainers.AveragedPerceptron()
.Fit(transformedData);
This gives me the exception on the line where I try to create the model:
Schema mismatch for feature column 'Features': expected Vector<Single>, got VarVector<Single> (Parameter 'inputSchema')
I'm guessing this is due to the fact these arrays all have variable lengths, but I don't see a way to transform the VarVector. Do I need to go make the original allReviews enumerable have the same length array for every array? Or am I way off track with how I flattened the original model?
Looks like it was a combination of changing the arrays to all have the same size, as well as adding [VectorType(size)] attribute to all the array properties.

How do I parse this JSON data in C# and would it be more benefical to simply switch over to javascript?

I'm looking to parse this JSON and I've had nothing but problems. The link to the JSON is here. I'm trying to access the "href" field. While writing this up, I realized that that the data field is actually an array so that is part of my problem.
class Program
{
static void Main(string[] args)
{
var json = System.IO.File.ReadAllText(#"C:\Users\...\file.json");
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(json);
var x = myDeserializedClass.result.extractorData.data;
Console.Write(x.ToString());
}
public class Newcolumn
{
public string text { get; set; }
public string xpath { get; set; }
public string href { get; set; }
public string filepath { get; set; }
public string fileMimeType { get; set; }
public int fileTotalBytes { get; set; }
public string fileLastModifiedTime { get; set; }
}
public class Group
{
public List<Newcolumn> Newcolumn { get; set; }
}
public class Datum
{
public List<Group> group { get; set; }
}
public class ExtractorData
{
public string url { get; set; }
public List<Datum> data { get; set; }
}
public class PageData
{
public int statusCode { get; set; }
public long timestamp { get; set; }
}
public class Inputs
{
public string _url { get; set; }
}
public class Result
{
public ExtractorData extractorData { get; set; }
public PageData pageData { get; set; }
public Inputs inputs { get; set; }
public string taskId { get; set; }
public long timestamp { get; set; }
public int sequenceNumber { get; set; }
}
public class Root
{
public string url { get; set; }
public Result result { get; set; }
}
}
This ends up returning: System.Collections.Generic.List`1[ConsoleApp3.Datum]
I notice that the field name data actually turns into an array though I'm not sure how to structure that. data.[0].new Column.[0].group.etc... does not work obviously. The space in the "new Column" field is also problematic. Additionally, when I debug and look at the JSON viewer, the "new column field is null. I also tried this code:
public static void Main()
{
var json = System.IO.File.ReadAllText(#"C:\Users\...\file.json");
dynamic stuff = JsonConvert.DeserializeObject(json);
var a = stuff.result.extractorData.data;
string b = a.ToString();
Console.WriteLine(b);
Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
This actually does return the data field object however, if I do stuff.result.extractorData.data.group; I get this:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
HResult=0x80131500
Message='Newtonsoft.Json.Linq.JArray' does not contain a definition for 'group'
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
I assume that this is probably because of the array contained within the data field, regardless the "new Column' field is also an issue with this method due to the space.
in your above code
public class ExtractorData
{
public string url { get; set; }
public List<Datum> data { get; set; }
}
where data is List and you are trying to access as string
Console.Write(x.ToString());
in data variable Datum is List ( where your variable have multiple Data) and in every element there is a List. (Nestest List Concept Applied in This JSON)
Try to Add Break Point on below Line and check the line by line Excution of Code.
var a = stuff.result.extractorData.data;
After Looking Your JSON File Image Try This Code
Console.Write(a.FirstOrDefault()?.group.FirstOrDefault()?.Newcolumn.FirstOrDefault()?.href);

JSON invalid format

I'm trying to deserialize the JSON from the weather API, I have created C# classes but I can't seem to get it working. Most sites display this JSON as invalid format, so I'm not really sure whats wrong with it. Here is the JSON string and my class for Deserializing.Visual studio displays it like any other regular JSON.
"[\"cod\":\"200\",\"message\":0,\"cnt\":40,\"list\":[[\"dt\":1574175600,\"main\":[\"temp\":284.79,\"temp_min\":282.63,\"temp_max\":284.79,\"pressure\":1021,\"sea_level\":1021,\"grnd_level\":958,\"humidity\":88,\"temp_kf\":2.16],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3,\"deg\":51],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-19 15:00:00\"],[\"dt\":1574186400,\"main\":[\"temp\":282.92,\"temp_min\":281.3,\"temp_max\":282.92,\"pressure\":1021,\"sea_level\":1021,\"grnd_level\":958,\"humidity\":94,\"temp_kf\":1.62],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.93,\"deg\":53],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-19 18:00:00\"],[\"dt\":1574197200,\"main\":[\"temp\":282.6,\"temp_min\":281.52,\"temp_max\":282.6,\"pressure\":1021,\"sea_level\":1021,\"grnd_level\":957,\"humidity\":93,\"temp_kf\":1.08],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.84,\"deg\":64],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-19 21:00:00\"],[\"dt\":1574208000,\"main\":[\"temp\":281.67,\"temp_min\":281.13,\"temp_max\":281.67,\"pressure\":1020,\"sea_level\":1020,\"grnd_level\":956,\"humidity\":94,\"temp_kf\":0.54],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.83,\"deg\":65],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-20 00:00:00\"],[\"dt\":1574218800,\"main\":[\"temp\":280.97,\"temp_min\":280.97,\"temp_max\":280.97,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":954,\"humidity\":96,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.9,\"deg\":57],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-20 03:00:00\"],[\"dt\":1574229600,\"main\":[\"temp\":280.72,\"temp_min\":280.72,\"temp_max\":280.72,\"pressure\":1016,\"sea_level\":1016,\"grnd_level\":953,\"humidity\":96,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":90],\"wind\":[\"speed\":3.65,\"deg\":65],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-20 06:00:00\"],[\"dt\":1574240400,\"main\":[\"temp\":282.34,\"temp_min\":282.34,\"temp_max\":282.34,\"pressure\":1015,\"sea_level\":1015,\"grnd_level\":953,\"humidity\":91,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":1.32,\"deg\":78],\"rain\":[\"3h\":1.19],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-20 09:00:00\"],[\"dt\":1574251200,\"main\":[\"temp\":283.44,\"temp_min\":283.44,\"temp_max\":283.44,\"pressure\":1015,\"sea_level\":1015,\"grnd_level\":952,\"humidity\":87,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.16,\"deg\":79],\"rain\":[\"3h\":1.94],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-20 12:00:00\"],[\"dt\":1574262000,\"main\":[\"temp\":282.5,\"temp_min\":282.5,\"temp_max\":282.5,\"pressure\":1015,\"sea_level\":1015,\"grnd_level\":952,\"humidity\":90,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.21,\"deg\":75],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-20 15:00:00\"],[\"dt\":1574272800,\"main\":[\"temp\":281.27,\"temp_min\":281.27,\"temp_max\":281.27,\"pressure\":1016,\"sea_level\":1016,\"grnd_level\":953,\"humidity\":88,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"]],\"clouds\":[\"all\":80],\"wind\":[\"speed\":1.94,\"deg\":105],\"rain\":[\"3h\":0.38],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-20 18:00:00\"],[\"dt\":1574283600,\"main\":[\"temp\":280.14,\"temp_min\":280.14,\"temp_max\":280.14,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":954,\"humidity\":90,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"]],\"clouds\":[\"all\":0],\"wind\":[\"speed\":1.72,\"deg\":131],\"rain\":[\"3h\":0.19],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-20 21:00:00\"],[\"dt\":1574294400,\"main\":[\"temp\":279.7,\"temp_min\":279.7,\"temp_max\":279.7,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":954,\"humidity\":89,\"temp_kf\":0],\"weather\":[[\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01n\"]],\"clouds\":[\"all\":0],\"wind\":[\"speed\":1.53,\"deg\":122],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-21 00:00:00\"],[\"dt\":1574305200,\"main\":[\"temp\":279.29,\"temp_min\":279.29,\"temp_max\":279.29,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":954,\"humidity\":89,\"temp_kf\":0],\"weather\":[[\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01n\"]],\"clouds\":[\"all\":0],\"wind\":[\"speed\":1.71,\"deg\":110],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-21 03:00:00\"],[\"dt\":1574316000,\"main\":[\"temp\":278.99,\"temp_min\":278.99,\"temp_max\":278.99,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":90,\"temp_kf\":0],\"weather\":[[\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01d\"]],\"clouds\":[\"all\":0],\"wind\":[\"speed\":1.76,\"deg\":106],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-21 06:00:00\"],[\"dt\":1574326800,\"main\":[\"temp\":284.12,\"temp_min\":284.12,\"temp_max\":284.12,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":954,\"humidity\":71,\"temp_kf\":0],\"weather\":[[\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01d\"]],\"clouds\":[\"all\":0],\"wind\":[\"speed\":1.91,\"deg\":94],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-21 09:00:00\"],[\"dt\":1574337600,\"main\":[\"temp\":286.38,\"temp_min\":286.38,\"temp_max\":286.38,\"pressure\":1016,\"sea_level\":1016,\"grnd_level\":953,\"humidity\":62,\"temp_kf\":0],\"weather\":[[\"id\":801,\"main\":\"Clouds\",\"description\":\"few clouds\",\"icon\":\"02d\"]],\"clouds\":[\"all\":21],\"wind\":[\"speed\":2.19,\"deg\":66],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-21 12:00:00\"],[\"dt\":1574348400,\"main\":[\"temp\":282.01,\"temp_min\":282.01,\"temp_max\":282.01,\"pressure\":1016,\"sea_level\":1016,\"grnd_level\":953,\"humidity\":91,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.67,\"deg\":46],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-21 15:00:00\"],[\"dt\":1574359200,\"main\":[\"temp\":280.86,\"temp_min\":280.86,\"temp_max\":280.86,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":954,\"humidity\":94,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":86],\"wind\":[\"speed\":2.78,\"deg\":49],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-21 18:00:00\"],[\"dt\":1574370000,\"main\":[\"temp\":280.55,\"temp_min\":280.55,\"temp_max\":280.55,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":92,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.52,\"deg\":56],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-21 21:00:00\"],[\"dt\":1574380800,\"main\":[\"temp\":280.04,\"temp_min\":280.04,\"temp_max\":280.04,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":953,\"humidity\":95,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.6,\"deg\":53],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-22 00:00:00\"],[\"dt\":1574391600,\"main\":[\"temp\":280.1,\"temp_min\":280.1,\"temp_max\":280.1,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":953,\"humidity\":96,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.54,\"deg\":49],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-22 03:00:00\"],[\"dt\":1574402400,\"main\":[\"temp\":281.29,\"temp_min\":281.29,\"temp_max\":281.29,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":953,\"humidity\":97,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":2.24,\"deg\":38],\"rain\":[\"3h\":0.44],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-22 06:00:00\"],[\"dt\":1574413200,\"main\":[\"temp\":280.84,\"temp_min\":280.84,\"temp_max\":280.84,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":93,\"temp_kf\":0],\"weather\":[[\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.21,\"deg\":33],\"rain\":[\"3h\":3.88],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-22 09:00:00\"],[\"dt\":1574424000,\"main\":[\"temp\":279.71,\"temp_min\":279.71,\"temp_max\":279.71,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":93,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.37,\"deg\":41],\"rain\":[\"3h\":2.81],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-22 12:00:00\"],[\"dt\":1574434800,\"main\":[\"temp\":278.48,\"temp_min\":278.48,\"temp_max\":278.48,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":93,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.59,\"deg\":49],\"rain\":[\"3h\":1.88],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-22 15:00:00\"],[\"dt\":1574445600,\"main\":[\"temp\":278.11,\"temp_min\":278.11,\"temp_max\":278.11,\"pressure\":1019,\"sea_level\":1019,\"grnd_level\":955,\"humidity\":93,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.55,\"deg\":49],\"rain\":[\"3h\":0.81],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-22 18:00:00\"],[\"dt\":1574456400,\"main\":[\"temp\":278.1,\"temp_min\":278.1,\"temp_max\":278.1,\"pressure\":1019,\"sea_level\":1019,\"grnd_level\":955,\"humidity\":93,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.67,\"deg\":49],\"rain\":[\"3h\":1.38],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-22 21:00:00\"],[\"dt\":1574467200,\"main\":[\"temp\":277.43,\"temp_min\":277.43,\"temp_max\":277.43,\"pressure\":1020,\"sea_level\":1020,\"grnd_level\":955,\"humidity\":93,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.15,\"deg\":47],\"rain\":[\"3h\":0.75],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-23 00:00:00\"],[\"dt\":1574478000,\"main\":[\"temp\":277.23,\"temp_min\":277.23,\"temp_max\":277.23,\"pressure\":1019,\"sea_level\":1019,\"grnd_level\":955,\"humidity\":92,\"temp_kf\":0],\"weather\":[[\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"]],\"clouds\":[\"all\":98],\"wind\":[\"speed\":3.5,\"deg\":59],\"rain\":[\"3h\":0.56],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-23 03:00:00\"],[\"dt\":1574488800,\"main\":[\"temp\":276.54,\"temp_min\":276.54,\"temp_max\":276.54,\"pressure\":1020,\"sea_level\":1020,\"grnd_level\":955,\"humidity\":95,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":98],\"wind\":[\"speed\":3.32,\"deg\":59],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-23 06:00:00\"],[\"dt\":1574499600,\"main\":[\"temp\":278.93,\"temp_min\":278.93,\"temp_max\":278.93,\"pressure\":1019,\"sea_level\":1019,\"grnd_level\":955,\"humidity\":86,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.36,\"deg\":56],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-23 09:00:00\"],[\"dt\":1574510400,\"main\":[\"temp\":280.06,\"temp_min\":280.06,\"temp_max\":280.06,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":954,\"humidity\":80,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.74,\"deg\":53],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-23 12:00:00\"],[\"dt\":1574521200,\"main\":[\"temp\":277.41,\"temp_min\":277.41,\"temp_max\":277.41,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":954,\"humidity\":89,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.84,\"deg\":55],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-23 15:00:00\"],[\"dt\":1574532000,\"main\":[\"temp\":276.83,\"temp_min\":276.83,\"temp_max\":276.83,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":92,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":96],\"wind\":[\"speed\":3.75,\"deg\":56],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-23 18:00:00\"],[\"dt\":1574542800,\"main\":[\"temp\":277.04,\"temp_min\":277.04,\"temp_max\":277.04,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":90,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":100],\"wind\":[\"speed\":3.55,\"deg\":61],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-23 21:00:00\"],[\"dt\":1574553600,\"main\":[\"temp\":275.99,\"temp_min\":275.99,\"temp_max\":275.99,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":96,\"temp_kf\":0],\"weather\":[[\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":81],\"wind\":[\"speed\":3.19,\"deg\":55],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-24 00:00:00\"],[\"dt\":1574564400,\"main\":[\"temp\":276.56,\"temp_min\":276.56,\"temp_max\":276.56,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":953,\"humidity\":96,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"]],\"clouds\":[\"all\":91],\"wind\":[\"speed\":3.02,\"deg\":62],\"sys\":[\"pod\":\"n\"],\"dt_txt\":\"2019-11-24 03:00:00\"],[\"dt\":1574575200,\"main\":[\"temp\":277.36,\"temp_min\":277.36,\"temp_max\":277.36,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":95,\"temp_kf\":0],\"weather\":[[\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":86],\"wind\":[\"speed\":2.99,\"deg\":62],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-24 06:00:00\"],[\"dt\":1574586000,\"main\":[\"temp\":280.51,\"temp_min\":280.51,\"temp_max\":280.51,\"pressure\":1018,\"sea_level\":1018,\"grnd_level\":954,\"humidity\":82,\"temp_kf\":0],\"weather\":[[\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04d\"]],\"clouds\":[\"all\":74],\"wind\":[\"speed\":3.05,\"deg\":64],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-24 09:00:00\"],[\"dt\":1574596800,\"main\":[\"temp\":282.87,\"temp_min\":282.87,\"temp_max\":282.87,\"pressure\":1016,\"sea_level\":1016,\"grnd_level\":953,\"humidity\":74,\"temp_kf\":0],\"weather\":[[\"id\":802,\"main\":\"Clouds\",\"description\":\"scattered clouds\",\"icon\":\"03d\"]],\"clouds\":[\"all\":42],\"wind\":[\"speed\":3.21,\"deg\":50],\"sys\":[\"pod\":\"d\"],\"dt_txt\":\"2019-11-24 12:00:00\"]],\"city\":[\"id\":787657,\"name\":\"Nis\",\"coord\":[\"lat\":43.3247,\"lon\":21.9033],\"country\":\"RS\",\"timezone\":3600,\"sunrise\":1574141412,\"sunset\":1574175927]]"
And my class for deserializing:
public class WeatherInfo
{
public class root
{
public string cod { get; set; }
public string message { get; set; }
public string cnt { get; set; }
public allLists list { get; set; }
public city city { get; set; }
}
public class allLists
{
allinfo[] allinfos { get; set; }
}
public class allinfo
{
public string dt { get; set; }
public main main { get; set; }
public allWeathers weather { get; set; }
public string dt_txt { get; set; }
}
public class main
{
public double temp { get; set; }
public double temp_min { get; set; }
public double temp_max { get; set; }
public double pressure { get; set; }
public double sea_level { get; set; }
public double grnd_level { get; set; }
public double humidity { get; set; }
public double temp_kf { get; set; }
}
public class allWeathers
{
public weather[] weathers { get; set; }
}
public class weather
{
public int id { get; set; }
public string main { get; set; }
public string description { get; set; }
public string icon { get; set; }
}
public class clouds
{
public double all { get; set; }
}
public class wind
{
public double speed { get; set; }
public double deg { get; set; }
}
public class sys
{
public string pod { get; set; }
}
public class city
{
public int id { get; set; }
public string name { get; set; }
public coord coord { get; set; }
public string country { get; set; }
public string timezone { get; set; }
public string sunrise { get; set; }
public string sunset { get; set; }
}
public class coord
{
public double lat { get; set; }
public double lon { get; set; }
}
}
Your JSON is not valid.
The main thing is that you are using brackets [] where you should be using braces {}.
In JSON [] is an array, while {} is an object. There are a couple of places where you need to have an array (e.g. list) so you can't simply do a find-replace to fix this.
An easy way to resolve this in the future is to create an instance of your WeatherInfo class, populate it with data, and then serialize it to JSON. You can then compare that with the JSON you have (using a diff tool like KDiff or WinMerge) to identify where your source JSON is different from your generated JSON.
A valid JSON always starts with a [ or a { and ends with the same, where square bracket [ represents an array and curly bracket { represents an object.
Looking at your C# class, your JSON lacks the curly brace to start with for objects and is also missing names for the arrays like allinfos.
You should start building your JSON like this:
var json = JToken.Parse
("{\"cod\":\"200\",\"message\":0,\"cnt\":40,\"list\":{\"allinfos\":[{\"dt\":1574175600, \"main\":{\"temp\":284.79,\"temp_min\":282.63,\"temp_max\":284.79,\"pressure\":1021,\"sea_level\":1021,\"grnd_level\":958,\"humidity\":88,\"temp_kf\":2.16}}]}}").ToString(Formatting.Indented);
This will give a formatted, easy to read output like this:
{
"cod": "200",
"message": 0,
"cnt": 40,
"list": {
"allinfos": [
{
"dt": 1574175600,
"main": {
"temp": 284.79,
"temp_min": 282.63,
"temp_max": 284.79,
"pressure": 1021,
"sea_level": 1021,
"grnd_level": 958,
"humidity": 88,
"temp_kf": 2.16
}
}
]
}
}
Update: The JSON was actually valid, the problem is that I was trying to work with debugging version of the string. The debugger automatically adds escape characters and "" quotes. Also some of the classes I had didn't follow up the JSON format correctly, so that error stopped me from seeing the real issue here.

How to fix Error while converting Json string to Object C#?

Im using C# to get a file from my local pc data folder.
This is the code to do that:
var _rootpath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + directory;
var ENC = new Encryption();
var s = File.ReadAllText(_rootpath + "json");
var x = ENC.RijndaelDecrypt(s, App.EncryptionPassword);
This works fine so far.
x got now this value (so this is the string I want to convert to an object) :
{
"items":[
{
"id":194,
"guid":"594394",
"name":"Test",
"connectorId":248,
"customerId":1,
"customerName":"company",
"connectorTypeId":10,
"connectorTypeIcon":null,
"connectorCategoryId":1,
"vendor":"FasterForward",
"isActive":true,
"shopId":null,
"sku":null,
"workerBearerToken":"",
"workerUri":"http://localhost:9000"
}
],
"responseStatus":null
}
After this I want to convert this to an object
var _response = JsonConvert.DeserializeObject<CrmJobListResponse>(x);
This line gives an error:
{"Error converting value x to type 'ServiceModel.CrmJobListResponse'. Path '', line 1, position 991."}
ServiceModel.CrmJobListResponse:
namespace ServiceModel
{
public class CrmJobListResponse : ResponseBase
{
public CrmJobListResponse();
public List<CrmJob> Items { get; set; }
}
}
CrmJob class:
namespace ServiceModel.DTO
{
public class CrmJob : IHasId<int>
{
public CrmJob();
[Ignore]
public string WorkerBearerToken { get; set; }
[PropertyValue("sku")]
public string SKU { get; set; }
[PropertyValue("shop_id")]
public string ShopId { get; set; }
public bool IsActive { get; set; }
public string Vendor { get; set; }
public int ConnectorCategoryId { get; set; }
[Ignore]
public string WorkerRefreshToken { get; set; }
public string ConnectorTypeIcon { get; set; }
public string CustomerName { get; set; }
public int CustomerId { get; set; }
public int ConnectorId { get; set; }
[PropertyValue("jobname")]
public string Name { get; set; }
public string Guid { get; set; }
public int Id { get; set; }
public int ConnectorTypeId { get; set; }
[Ignore]
public string WorkerUri { get; set; }
}
}
Does anyone know why it can't convert my Json string to an object?
I didn't made the code myself, but I don't see why It should go wrong...
If you have a hard time creating DTOs you have some tools that may assist you https://app.quicktype.io/
You can also use paste special in VS to paste a Json directy to a C# class.
This also shows you if you malformed a Json.

Categories

Resources