How to fix Error while converting Json string to Object C#? - 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.

Related

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

Not able validate data condition based on the json element attribute value from a json using c#

I have a json file, where i have to validate a json attribute element value based on another json element attribute value. But if there json elements with the same name. It always takes the last value always instead of parsing the json data fully. Please guide me.
Below the sample json file
{
"PLMXML":{
"language":"en-us",
"author":"Developer",
"date":"2020-05-22",
"traverseRootRefs":"#id6",
"Operation":{
"id":"id21",
"subType":"BS4_BaOP",
"catalogueId":"70700000209604"
},
"Operation":{
"id":"id28",
"subType":"BS4_BaOP",
"catalogueId":"70700000209603"
},
"OperationRevision":{
"id":"id6",
"subType":"BS4_BaOPRevision",
"masterRef":"#id21",
"revision":"A1"
}
}
}
And below the code which im trying to use
public void Readjsonfile(string jsondata)
{
var message = JsonConvert.DeserializeObject<plmxmldatamodel>(jsondata);
if (String.Equals(message.PLMXML.traverseRootRefs.Substring(1), message.PLMXML.OperationRevision.id))
{
Console.WriteLine("Condtion1");
if (String.Equals(message.PLMXML.OperationRevision.masterRef.Substring(1), message.PLMXML.Operation.id))
{
Console.WriteLine("Condition_2");
//Do something based on the condtion
}
}
}
public class Operation
{
public string id { get; set; }
public string subType { get; set; }
public string catalogueId { get; set; }
}
public class OperationRevision
{
public string id { get; set; }
public string subType { get; set; }
public string masterRef { get; set; }
}
public class PLMXML
{
public string language { get; set; }
public string author { get; set; }
public string date { get; set; }
public string traverseRootRefs { get; set; }
public Operation Operation { get; set; }
public OperationRevision OperationRevision { get; set; }
}
public class plmxmldatamodel
{
public PLMXML PLMXML { get; set; }
}
When i try to dedug this in the second if condtion, the value for message.PLMXML.Operation.id is always id28 , because of which second if condition fails. While the first if condition is passed as there is only one message.PLMXML.OperationRevision.id. i wanted behaviour where it would check complete json data and check if message.PLMXML.Operation.id with value id21 is present or not , So my data gets passed. Please kindly guide me here.I am very new to C# here.
From my observation you have couple of issues.
What happen you have double keys, and your parser taking the last value not the first one.
First of all your json should be corrected. I assume you have access to change your json and operation should be an array like follow:
{
"PLMXML":{
"language":"en-us",
"author":"Developer",
"date":"2020-05-22",
"traverseRootRefs":"#id6",
"Operations":[
{
"id":"id21",
"subType":"BS4_BaOP",
"catalogueId":"70700000209604"
},
{
"id":"id28",
"subType":"BS4_BaOP",
"catalogueId":"70700000209603"
}
],
"OperationRevision":{
"id":"id6",
"subType":"BS4_BaOPRevision",
"masterRef":"#id21",
"revision":"A1"
}
}
}
When array in place than use an online tool like to validate your json and use this tool to create a model.
Your model will be like this:
public partial class PlmxmlDataModel
{
[JsonProperty("PLMXML")]
public Plmxml Plmxml { get; set; }
}
public partial class Plmxml
{
[JsonProperty("language")]
public string Language { get; set; }
[JsonProperty("author")]
public string Author { get; set; }
[JsonProperty("date")]
public DateTimeOffset Date { get; set; }
[JsonProperty("traverseRootRefs")]
public string TraverseRootRefs { get; set; }
[JsonProperty("Operations")]
public Operation[] Operations { get; set; }
[JsonProperty("OperationRevision")]
public OperationRevision OperationRevision { get; set; }
}
public partial class OperationRevision
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("subType")]
public string SubType { get; set; }
[JsonProperty("masterRef")]
public string MasterRef { get; set; }
[JsonProperty("revision")]
public string Revision { get; set; }
}
public partial class Operation
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("subType")]
public string SubType { get; set; }
[JsonProperty("catalogueId")]
public string CatalogueId { get; set; }
}
And your method like this:
public void Readjsonfile(string jsondata)
{
var message = JsonConvert.DeserializeObject<PlmxmlDataModel>(jsondata);
if (String.Equals(message.Plmxml.TraverseRootRefs.Substring(1), message.Plmxml.OperationRevision.Id))
{
Console.WriteLine("Condtion1");
if (String.Equals(message.Plmxml.OperationRevision.MasterRef.Substring(1), message.Plmxml.Operations[0].Id))
{
Console.WriteLine("Condition_2");
//Do something based on the condtion
}
}
}
Now in your method I am looking for array index 0 with contain id 28, but if you are look for id 28 in any of the array then you can do some thing like:
if (message.Plmxml.Operations.Any(e => e.Id == message.Plmxml.OperationRevision.MasterRef.Substring(1)))

nested json deserialization - need another set of eyes

I have been trying to get this json to deserialize for two days now using RestSharp. I have gone through the RestSharp github site, looked at countless examples, and spent much time here on Stack Overflow to try and find the answer to no avail. My code had previously worked perfectly but the vendor changed their API version and I was forced to do an update to keep using the application for my legal practice. My json is as follows(client info has been removed and replaced with generic info):
{
"data":[
{
"id":1035117666,
"client":
{
"id":905422394,
"name":"client1"
},
"display_number":"11-00012",
"description":"General",
"practice_area":
{
"id":4269978,
"name":"Business"
},
"status":"Open",
"open_date":"2011-12-14",
"close_date":null,
"billing_method":"hourly"
},
{
"id":1035117768,
"client":
{
"id":905422506,
"name":"client2"
},
"display_number":"12-00037",
"description":"HOA",
"practice_area":
{
"id":4269978,
"name":"Business"
},
"status":"Open",
"open_date":"2012-08-07",
"close_date":null,
"billing_method":"hourly"
}
],
"meta":
{
"paging":
{
"next":"https://app.goclio.com/api/v4/matters.json?fields=id%2C+client%7Bid%2C+name%7D%2C+display_number%2C+description%2C+practice_area%7Bid%2C+name%7D%2C+status%2C+open_date%2C+close_date%2C+billing_method&limit=2&page_token=BAh7BjoLb2Zmc2V0aQc%3D--b1ea3eba20c8acefbcdfc7868debd1e0ee630c64&status=Open"
},
"records":91
}
}
I built the following schema within my c# code:
public class MatterList
{
public List<Matter> matters { get; set; }
public Meta meta { get; set; }
}
public class Meta
{
public Paging paging { get; set; }
public int records { get; set; }
}
public class Paging
{
public string previous { get; set; }
public string next { get; set; }
}
[DeserializeAs(Name = "data")]
public class Matter
{
public int id { get; set; }
public Client client { get; set; }
public string display_number { get; set; }
public string description { get; set; }
public PracticeArea practice_area { get; set; }
public string status { get; set; }
public DateTime open_date { get; set; }
public DateTime close_date { get; set; }
public string billing_method { get; set; }
public string type = "matter";
}
public class PracticeArea
{
public int id { get; set; }
public string name { get; set; }
}
public class Client
{
public int id { get; set; }
public string name { get; set; }
}
When I run the RestSharp deserialize method I am sending the result to an object of type MatterList using the following line of code
MatterList matterList = jsonHandler.Deserialize<MatterList>(response);
I have so far attempted to deserialize without the Meta or Paging POCO classes with the accompanying change to the MatterList class (taking out the Meta property).
I have tried with and without the [DeserializeAs(Name="data")] directive.
I have tried to set the RootElement of the json response prior to deserialization.
I have tried to shorthand the deserialization by combining it with the Execute request code
IRestResponse<MatterList> matterList = client.Execute<MatterList>(request);
I have created a container class called MatterContainer which I placed between MatterList and Matter classes in the schema:
public class MatterList
{
public List<MatterContainer> matters { get; set; }
}
public class MatterContainer
{
public Matter matter { get; set; }
}
public class Matter
{
public int id { get; set; }
public Client client { get; set; }
public string display_number { get; set; }
public string description { get; set; }
public PracticeArea practice_area { get; set; }
public string status { get; set; }
public DateTime open_date { get; set; }
public DateTime close_date { get; set; }
public string billing_method { get; set; }
public string type = "matter";
}
I know I am getting the json response back from the server correctly so my request is proper and MatterList is not null after deserialization. The problem is that I cannot get the deserialization to actually populate the List matters within the MatterList class.
I have been looking at this off and on for two days and cannot get past this hurdle. If anyone sees what I did wrong I would greatly appreciate the insight, I am at a point where I cannot progress further with my application.
Thanks!
I think your [DeserializeAs(Name = "data")] attribute is in the wrong place. Try putting it in the root class instead:
public class MatterList
{
[DeserializeAs(Name = "data")]
public List<Matter> matters { get; set; }
public Meta meta { get; set; }
}
alternatively, try renameing that property to data

JSON C# DeserializeObject Error with Newtonsoft.Json

I have a JSON string that I am getting from the BaseCamp API. I know for a fact that the JSON is valid, however, I am not able to DeserializeObject using Newtonsoft.Json.
I get an error saying:
Cannot deserialize the current JSON array (e.g.[1,2,3]) into type BaseCamp.Code.Projects+RootObject because the type requires a JSON objet (e.g. {"name":"value"}) to deserialize correctly.
The JSON (Unformated What is returned from the API Minus the URL's Values)
[
{
"id":6656986,
"name":"Physics Revamp",
"description":"ISU department of physics website redesign",
"archived":false,
"is_client_project":true,
"created_at":"2014-08-07T10:59:29.000-05:00",
"updated_at":"2014-10-30T09:18:01.000-05:00",
"trashed":false,
"color":"2c5322",
"draft":false,
"template":false,
"last_event_at":"2014-10-30T09:18:01.000-05:00",
"starred":false,
"url":"xxxxxxxxxxxxxxxxxxxxxxx",
"app_url":"xxxxxxxxxxxxxxx"
},
{
"id":7178664,
"name":"Physics Videos",
"description":"",
"archived":false,
"is_client_project":false,
"created_at":"2014-10-02T08:34:46.000-05:00",
"updated_at":"2014-10-23T08:40:17.000-05:00",
"trashed":false,
"color":"660099",
"draft":false,
"template":false,
"last_event_at":"2014-10-23T08:40:17.000-05:00",
"starred":false,
"url":"xxxxxxxxxxxxxxxxxxxxxxx",
"app_url":"xxxxxxxxxxxxxxxxxxx"
},
{
"id":6685451,
"name":"WZND Website 2014",
"description":"",
"archived":false,
"is_client_project":true,
"created_at":"2014-08-11T13:25:51.000-05:00",
"updated_at":"2014-10-30T11:26:39.000-05:00",
"trashed":false,
"color":"3185c5",
"draft":false,
"template":false,
"last_event_at":"2014-10-30T11:26:39.000-05:00",
"starred":false,
"url":"xxxxxxxxxxxxxxxxxx",
"app_url":"xxxxxxxxxxxxxxxxx"
}
]
My C# class:
public class Projects
{
public class RootObject
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public bool archived { get; set; }
public bool is_client_project { get; set; }
public string created_at { get; set; }
public string updated_at { get; set; }
public bool trashed { get; set; }
public string color { get; set; }
public bool draft { get; set; }
public bool template { get; set; }
public string last_event_at { get; set; }
public bool starred { get; set; }
public string url { get; set; }
public string app_url { get; set; }
}
}
I am assuming something is wrong with the way my class is set up, but I can't see it.
You need to convert to an array of RootObject:
var json = JsonConvert.DeserializeObject<Projects.RootObject[]>(response);
or list (or any other collection you want for that matter)...
var json = JsonConvert.DeserializeObject<List<Projects.RootObject>>(response);

C# - LINQToExcel - Null Values

I'm trying to learn how to use LINQTOExcel to query a CSV file. Following the tutorial on the site I adapted their example to work with my data (filename is passed to it via an OpenDialog component):
var csv = new ExcelQueryFactory(filename);
var test = from c in csv.Worksheet<TestData>()
select c;
foreach(var t in test)
{
Console.WriteLine(t.Contract_Id);
}
I've got a separate TestData class/model which looks like this:
class TestData
{
public string Transaction_Id { get; set; }
public string Value_Date { get; set; }
public string Transmit_Date { get; set; }
public string Transmit_Time { get; set; }
public string Contract_Id { get; set; }
public string Contract_Amount { get; set; }
public string Contract_Rage { get; set; }
public string TestAmount { get; set; }
public string Employer_Code { get; set; }
public string Test_Acceptor { get; set; }
public string Institution_Id { get; set; }
}
But when I loop through, all of the values for each item are 'null'. Am I missing a step somewhere?
Example CSV Data:
transaction_id,value_date,transmit_date,transmit_time,contract_no,contract_amount,instalment,test_amount,employer_code,test_acceptor,institution_id
35454521,20111230,20120102,2:23:12,1442,1714.56,1,285.76,0,643650,a
The CSV file needs a header row that matches the property names:
Transaction_Id,Value_Date,Transmit_Date,Transmit_Time,Contract_Id,Contract_Amount,Contract_RageTestAmount,Employer_Code,Test_Acceptor,Institution_Id
35454521,20111230,20120102,2:23:12,1442,1714.56,1,285.76,0,643650

Categories

Resources