i've some problems when i'm trying to read a Yaml file using c# and need help to finish this task , how can i read a such Yaml file into variables so i can treat them .
FileConfig:
sourceFolder: /home
destinationFolder: /home/billy/my-test-case
scenarios:
- name: first-scenario
alterations:
- tableExtension: ln
alterations:
- type: copy-line
sourceLineIndex: 0
destinationLineIndex: 0
- type: cell-change
sourceLineIndex: 0
columnName: FAKE_COL
newValue: NEW_Value1
- tableExtension: env
alterations:
- type: cell-change
sourceLineIndex: 0
columnName: ID
newValue: 10
Here is my code
string text = System.IO.File.ReadAllText(#"test.yaml");
var deserializer = new Deserializer();
var result = deserializer.Deserialize<List<Hashtable>>(new StringReader(text));
/*foreach (var item in result)
{
Console.WriteLine("Item:");
Console.WriteLine(item.GetType());
foreach (DictionaryEntry entry in item)
{
Console.WriteLine("- {0} = {1}", entry.Key, entry.Value);
}
} */
The easiest way is to create a C# model of your document. Then you are able to use the Deserializer to fill that model with the data present into the document. A possible model for your document would be:
public class MyModel
{
[YamlMember(Alias = "FileConfig", ApplyNamingConventions = false)]
public FileConfig FileConfig { get; set; }
}
public class FileConfig
{
public string SourceFolder { get; set; }
public string DestinationFolder { get; set; }
public List<Scenario> Scenarios { get; set; }
}
public class Scenario
{
public string Name { get; set; }
public List<Alteration> Alterations { get; set; }
}
public class Alteration
{
public string TableExtension { get; set; }
public List<TableAlteration> Alterations { get; set; }
}
public class TableAlteration
{
public string Type { get; set; }
public int SourceLineIndex { get; set; }
public int DestinationLineIndex { get; set; }
public string ColumnName { get; set; }
public string NewValue { get; set; }
}
You can deserialize to that model as follows:
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
var obj = deserializer.Deserialize<MyModel>(yaml);
You can run this code here: https://dotnetfiddle.net/SRABFM
Of course, the model that I suggest here is very naive and with more knowledge about your domain model, you will certainly be able to come up with a better one.
Related
I'm running into issues parsing a json reponse from GraphQL. The issue is the array will come back with more arrays half the time. My code is just getting out of hand and ugly.
Json file (trimmed it a bit. It can be 20+ data arrays)
{
"activity_logs": [
{
"data": "{\"board_id\":2165785546,\"group_id\":\"new_group2051\",\"is_top_group\":false,\"pulse_id\":2165787062,\"pulse_name\":\"Tyler\",\"column_id\":\"email_address\",\"column_type\":\"email\",\"column_title\":\"Email Address\",\"value\":{\"column_settings\":{\"includePulseInSubject\":true,\"ccPulse\":true,\"bccList\":\"\"}},\"previous_value\":{\"email\":\"tyler#email.com\",\"text\":\"tyler#email.com\",\"changed_at\":\"2022-02-15T21:18:48.297Z\",\"column_settings\":{\"includePulseInSubject\":true,\"ccPulse\":true,\"bccList\":\"\"}},\"is_column_with_hide_permissions\":false,\"previous_textual_value\":\"tyler#email.com\"}"
},
{
"data": "{\"board_id\":2165785546,\"group_id\":\"new_group2051\",\"is_top_group\":false,\"pulse_id\":216578711,\"pulse_name\":\"Nicholas \",\"column_id\":\"email_address\",\"column_type\":\"email\",\"column_title\":\"Email Address\",\"value\":{\"column_settings\":{\"includePulseInSubject\":true,\"ccPulse\":true,\"bccList\":\"\"}},\"previous_value\":{\"email\":\"nicholas#email.com\",\"text\":\"nicholas#email.com\",\"changed_at\":\"2022-02-16T04:44:52.046Z\",\"column_settings\":{\"includePulseInSubject\":true,\"ccPulse\":true,\"bccList\":\"\"}},\"is_column_with_hide_permissions\":false,\"previous_textual_value\":\"nicholas#email.com\"}"
},
{
"data": "{\"board_id\":2165785546,\"group_id\":\"new_group2051\",\"is_top_group\":false,\"pulse_id\":216578711,\"pulse_name\":\"Nicholas \",\"column_id\":\"batch_5\",\"column_type\":\"text\",\"column_title\":\"Batch #\",\"value\":{\"value\":\"75\"},\"previous_value\":{\"value\":\"74\"},\"is_column_with_hide_permissions\":false}"
},
{
"data": "{\"board_id\":2165785546,\"group_id\":\"new_group2051\",\"pulse_id\":216578711,\"is_top_group\":false,\"value\":{\"name\":\"Nicholas \"},\"previous_value\":{\"name\":\"Nicholas \"},\"column_type\":\"name\",\"column_title\":\"Name\"}"
}
]
}
Random "get it to work" attempt after giving up on making is a List based on a Class. The IContainers within IContainers were getting very complex.
var responseData = JObject.Parse(responseText).SelectToken("data").SelectToken("boards").SelectToken("activity_logs");
dynamic updatedRecords = JsonConvert.DeserializeObject(responseData.ToString());
foreach (var record in updatedRecords)
{
List<Dictionary<string, string>> records = new List<Dictionary<string, string>>();
Dictionary<string, string> fields = new Dictionary<string, string>();
dynamic updates = JsonConvert.DeserializeObject(JObject.Parse(record.ToString()).SelectToken("data").ToString());
foreach(var update in updates)
{
switch (update.Name.ToString())
{
case "column_id":
fields.Add(update.Name.ToString(), update.Value.ToString());
break;
case "pulse_name":
fields.Add(update.Name.ToString(), update.Value.ToString());
break;
case "value":
dynamic values = JsonConvert.DeserializeObject(JObject.Parse(update.Value.ToString()));
if (update.Name.ToString().Contains("column_settings"))
{
foreach (var value in values)
{
dynamic columns = JsonConvert.DeserializeObject(JObject.Parse(value.Value.ToString()));
foreach(var column in columns)
{
fields.Add($"Value_{column.Name.ToString()}", column.Value.ToString());
}
}
}
else
{
foreach (var value in values)
{
fields.Add($"Value_{value.Name.ToString()}", value.Value.ToString());
}
}
break;
case "previous_value":
dynamic prevValues = JsonConvert.DeserializeObject(JObject.Parse(update.Value.ToString()));
foreach (var prevalue in prevValues)
{
fields.Add($"Prevalue_{prevalue.Name.ToString()}", prevalue.Value.ToString());
}
break;
case "previous_textual_value":
fields.Add(update.Name.ToString(), update.Value.ToString());
break;
}
}
if (fields.Count > 0)
{
records.Add(fields);
fields.Clear();
}
}
My Error when I get to:
dynamic values = JsonConvert.DeserializeObject(JObject.Parse(update.Value.ToString()));
- $exception {"The best overloaded method match for 'Newtonsoft.Json.JsonConvert.DeserializeObject(string)' has some invalid arguments"} Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
Solution is a big help and led to my answer. The issue is the activity_logs data comes with escape characters in it so the string contains \\".
I had to format the data sections with Replace("\\", "") and Replace("\"{", "{") and Replace("}\""), "}"). This made the string readable as a Json file.
You have to pass in a string to DeserializeObject instead of a JSON object.
Another way would be get your JSON mapped to a POCO types as follows, easy way to do is on Visual Studio (Copy your JSON contents, on Visual Studio create a new empty class -> Edit-> Past Special -> Paste JSON as classes)
public class LogsRoot
{
public Activity_Logs[] activity_logs { get; set; }
}
public class Activity_Logs
{
public string data { get; set; }
}
public class DataRoot
{
public long board_id { get; set; }
public string group_id { get; set; }
public bool is_top_group { get; set; }
public long pulse_id { get; set; }
public string pulse_name { get; set; }
public string column_id { get; set; }
public string column_type { get; set; }
public string column_title { get; set; }
public Value value { get; set; }
public Previous_Value previous_value { get; set; }
public bool is_column_with_hide_permissions { get; set; }
public string previous_textual_value { get; set; }
}
public class Value
{
public Column_Settings column_settings { get; set; }
}
public class Column_Settings
{
public bool includePulseInSubject { get; set; }
public bool ccPulse { get; set; }
public string bccList { get; set; }
}
public class Previous_Value
{
public string email { get; set; }
public string text { get; set; }
public DateTime changed_at { get; set; }
public Column_Settings1 column_settings { get; set; }
}
public class Column_Settings1
{
public bool includePulseInSubject { get; set; }
public bool ccPulse { get; set; }
public string bccList { get; set; }
}
Then load the JSON and manipulate as follows,
var json = File.ReadAllText("data.json");
var rootLogs = JsonConvert.DeserializeObject<LogsRoot>(json);
Dictionary<string, string> fields = new Dictionary<string, string>();
foreach (var logJson in rootLogs.activity_logs)
{
var log = JsonConvert.DeserializeObject<DataRoot>(logJson.data);
fields.Add(log.column_id, log.value.column_settings.bccList + log.value.column_settings.ccPulse);
fields.Add(log.pulse_name, log.value.column_settings.bccList + log.value.column_settings.ccPulse);
fields.Add(log.previous_value.email, log.value.column_settings.bccList + log.value.column_settings.ccPulse);
fields.Add(log.previous_textual_value, log.value.column_settings.bccList + log.value.column_settings.ccPulse);
}
This might not solve all your issues, but for the specific exception you are running into, it is because you are trying to deserialize a JObject instead of string.
Probably you just want:
dynamic values = JsonConvert.DeserializeObject(update.Value.ToString());
My project has a 3rd party web API that returns a json string in the following format (including the starting and ending curly braces):
{
"866968030210604":{
"dt_server":"2019-02-07 12:21:27",
"dt_tracker":"2019-02-07 12:21:27",
"lat":"28.844968",
"lng":"76.858502",
"altitude":"0",
"angle":"154",
"speed":"9",
"params":{
"pump":"0",
"track":"1",
"bats":"1",
"acc":"0",
"batl":"4"
},
"loc_valid":"1"
},
"866968030221205":{
"dt_server":"2019-02-07 12:20:24",
"dt_tracker":"2019-02-07 12:19:41",
"lat":"28.845904",
"lng":"77.096063",
"altitude":"0",
"angle":"0",
"speed":"0",
"params":{
"pump":"0",
"track":"1",
"bats":"1",
"acc":"0",
"batl":"4"
},
"loc_valid":"1"
},
"866968030212030":{
"dt_server":"0000-00-00 00:00:00",
"dt_tracker":"0000-00-00 00:00:00",
"lat":"0",
"lng":"0",
"altitude":"0",
"angle":"0",
"speed":"0",
"params":null,
"loc_valid":"0"
}
}
I want to deserialize it into a c# class object for further processing. I made the following class structure for the same:
class Params
{
public string pump { get; set; }
public string track { get; set; }
public string bats { get; set; }
public string acc { get; set; }
public string batl { get; set; }
}
class GPSData
{
public string dt_server { get; set; }
public string dt_tracker { get; set; }
public string lat { get; set; }
public string lng { get; set; }
public string altitude { get; set; }
public string angle { get; set; }
public string speed { get; set; }
public Params ObjParams { get; set; }
public string loc_valid { get; set; }
}
and I am trying the following code to deserialize:
JavaScriptSerializer jSerObj = new JavaScriptSerializer();
List<GPSData> lstGPSData = (List<GPSData>)jSerObj.Deserialize(json, typeof(List<GPSData>));
But every time it is showing NULL values assigned to each property of the class after the Deserialize() method is called. Please help me on this.
Your json is not in list format so deserializing to List<> isn't work
So you need to deserialize it into Dictionary<string, GPSData> like
JavaScriptSerializer jSerObj = new JavaScriptSerializer();
Dictionary<string, GPSData> lstGPSData = (Dictionary<string, GPSData>)jSerObj.Deserialize(json, typeof(Dictionary<string, GPSData>));
Usage:
foreach (var item in lstGPSData)
{
string key = item.Key;
GPSData gPSData = item.Value;
}
Also, you can list all your GPSData from above dictionary like,
List<GPSData> gPSDatas = lstGPSData.Values.ToList();
Output: (From Debugger)
I am trying to read in a json file which is very complex into a JArray that can be accessed dynamically in a foreach statement. However I am getting an error which is stating 'Current JsonReader item is not an Array' I am able to access the keys and values if I use a JObject but that is not what I need I need to be able to go through the records and search by names or IDs, etc. I am a bit new at newtwonsoft and JSON.net so any help would be appreciated!
JArray o1 = JArray.Parse(File.ReadAllText(#"myfilepath"));
dynamic records = o1;
foreach (dynamic record in records)
{
Console.WriteLine(record.Id + " (" + record.Name + ")");
}
My json file looks like this, there are multiple records however I have shortened it. I need to access and search by Id or Name however I am having issues accessing.
String json = #"{
"RecordSetBundles" : [ {
"Records" : [ {
"attributes" : {
"type" : "nihrm__Location__c",
"url" : "/services/data/v38.0/sobjects/nihrm__Location__c/a0di0000001nI3oAAE"
},
"CurrencyIsoCode" : "USD",
"Id" : "a0di0000001nI3oAAE",
"Name" : "The City Hotel",
"nihrm__Abbreviation__c" : "TCH",
"nihrm__AddressLine1__c" : "1 Main Street",
"nihrm__AlternateNameES__c" : "El Ciudad Hotel",
"nihrm__AvailabilityScreenView__c" : "Combined",
"nihrm__Geolocation__c" : null,
"nihrm__HideBookingsFromPortal__c" : false,
"nihrm__IsActive__c" : true,
"nihrm__IsPlannerPortalEnabled__c" : false,
"nihrm__isRemoveCancelledEventsFromBEOs__c" : false,
"nihrm__ManagementAffliation__c" : "NI International",
"nihrm__NearestAirportCode__c" : "MHT",
"nihrm__Phone__c" : "(207) 555-5555",
"nihrm__PostalCode__c" : "04103",
"nihrm__PropertyCode__c" : "TCH",
"nihrm__RegionName__c" : "Northeast",
"nihrm__RestrictBookingMoveWithPickup__c" : true,
"nihrm__RohAllowedStatuses__c" : "Prospect;Tentative;Definite",
"nihrm__StateProvince__c" : "ME",
"nihrm__SystemOfMeasurement__c" : "Standard",
"nihrm__TimeZone__c" : "GMT-05:00 Eastern Daylight Time (America/New_York)",
"nihrm__UpdateBookingEventAverageChecks__c" : false,
"nihrm__UseAlternateLanguage__c" : false,
"nihrm__Website__c" : "www.thecityhotelweb.com"
} ],
"ObjectType" : "nihrm__Location__c",
"DeleteFirst" : false
},
Here is a link to the entire json:
https://codeshare.io/rGL6K5
The other answers show strong typed classes. If you can do this and you're sure the structure won't change I'd recommend doing it that way. It'll make everything else much easier.
If you want to do it with a dynamic object, then you can get what you want this way.
// GET JSON DATA INTO DYNAMIC OBJECT
var data = JsonConvert.DeserializeObject<dynamic>(File.ReadAllText(#"myfilepath"));
// GET TOP LEVEL "RecordSetBundles" OBJECT
var bundles = data.RecordSetBundles;
// LOOP THROUGH EACH BUNDLE OF RECORDS
foreach (var bundle in bundles)
{
// GET THE RECORDS IN THIS BUNDLE
var records = bundle.Records;
// LOOP THROUGH THE RECORDS
foreach (var record in records)
{
// WRITE TO CONSOLE
Console.WriteLine(record.Id.ToString() + " (" + record.Name.ToString() + ")");
}
}
Produces this output:
a0di0000001nI3oAAE (The City Hotel)
a0xi0000000jOQCAA2 (Rounds of 8)
a0xi0000001aUbfAAE (Additional Services)
a0xi0000004ZnehAAC (Citywide)
a0xi0000001YXcCAAW (Cocktail Rounds)
etc etc
Do you know if the properties of your JSon object will be the same each time the request is made? Not the values, just the names? If so, create a concrete type and use JSonObjectSerializer to deserialize into an object. If should be able to create a dictionary collection on that object that deserialized your JSon data into Key Value pairs. Then you can iterate like any other collection via the Keys collection.
You don't really need to use dynamic objects unless you really don't know what you are dealing with on the input. Ascertain if your incoming data has consistent property names each time the request is made.
An example could be
var myData = JsonSerializer.Deserialize<myDataType>(incomingTextData);
myDataType would have a collection that can handle your array.
This error Current JsonReader item is not an Array is self explanatory: the object parsed is not an array.However without see the Json we can only suppose that this Json is an object and if you want use a dynamic object change the code as follow:
dynamic myJson = JsonConvert.DeserializeObject(File.ReadAllText(#"myfilepath"));
var currency = myJson.RecordSetBundles[0].Records[0].CurrencyIsoCode
//Access to other property in your dynamic object
EDIT
Your JSON object seems quite complex and access via dynamic can be complex I suggest you to use JsonConvert.DeserializeObject<T>(string).
From the json that yoou have posted the class looks like this:
public class Attributes
{
public string type { get; set; }
public string url { get; set; }
}
public class Record
{
public Attributes attributes { get; set; }
public string CurrencyIsoCode { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public string nihrm__Abbreviation__c { get; set; }
public string nihrm__AddressLine1__c { get; set; }
public string nihrm__AlternateNameES__c { get; set; }
public string nihrm__AvailabilityScreenView__c { get; set; }
public object nihrm__Geolocation__c { get; set; }
public bool nihrm__HideBookingsFromPortal__c { get; set; }
public bool nihrm__IsActive__c { get; set; }
public bool nihrm__IsPlannerPortalEnabled__c { get; set; }
public bool nihrm__isRemoveCancelledEventsFromBEOs__c { get; set; }
public string nihrm__ManagementAffliation__c { get; set; }
public string nihrm__NearestAirportCode__c { get; set; }
public string nihrm__Phone__c { get; set; }
public string nihrm__PostalCode__c { get; set; }
public string nihrm__PropertyCode__c { get; set; }
public string nihrm__RegionName__c { get; set; }
public bool nihrm__RestrictBookingMoveWithPickup__c { get; set; }
public string nihrm__RohAllowedStatuses__c { get; set; }
public string nihrm__StateProvince__c { get; set; }
public string nihrm__SystemOfMeasurement__c { get; set; }
public string nihrm__TimeZone__c { get; set; }
public bool nihrm__UpdateBookingEventAverageChecks__c { get; set; }
public bool nihrm__UseAlternateLanguage__c { get; set; }
public string nihrm__Website__c { get; set; }
}
public class RecordSetBundle
{
public List<Record> Records { get; set; }
public string ObjectType { get; set; }
public bool DeleteFirst { get; set; }
}
public class RootObject
{
public List<RecordSetBundle> RecordSetBundles { get; set; }
}
To deserialize it using Newtonsoft:
var myObject = JsonConvert.DeserializeObject<RootObject>(myJsonStrin);
I use the mongoDB C# driver 2.1.1 to store and retrieve documents in a mongoDb collection. This worked well so far until one document was CORRECTLY stored but could not be read back by the driver.
I got to that conclusion using robomongo (a user interface to monitor what's inside my collection) and manipulating the object stored.
It contains a collection of elements (around 4000 sub elements) and if I remove enough of it, the document is finally retrievable again.
The line of code used is:
public Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken))
{
return MongoQueryable.FirstOrDefaultAsync(_collection, predicate, cancellationToken);
}
Before you ask, what I first thought is that one specific element of my sub elements set had encountered some issues while being serialized/deserialized and was creating the issue. I tested by removing randomly elements of the collection, and just the number seems to be the root of the problem.
The text file size of the Json document represents around 11 Mb - I will try now to get the actual size of the object which would be more relevant.
Something else I can add is that in the mondoDb log file, there is one line that only appear when I try to select an "oversized" document :
2016-06-29T19:30:45.982+0200 I COMMAND [conn12] command MYCOLLECTIONDb.$cmd command: aggregate
{ aggregate: "XXXX", pipeline: [ { $match: { _id: "5773e0e9a1152d259c7d2e50" } }, { $limit: 1 } ]
, cursor: {} } keyUpdates:0 writeConflicts:0 numYields:0 reslen:4188200 locks:{ Global:
{ acquireCount: { r: 6 } }, MMAPV1Journal: { acquireCount:
{ r: 3 } }, Database: { acquireCount: { r: 3 } }, Collection: { acquireCount: { R: 3 } } } 109ms
(XXXX being my custom object)
So I'd like to know if you have any idea of what's causing this issue, any hint of where I should try to look, because I am running out of ideas :)
EDIT_1: That is basically the structure of my object :
[DataContract]
public class MyClass
{
[DataMember]
public string _id { get; set; }
[DataMember]
public string XmlPreference { get; set; }
[DataMember]
public string XmlMarketDates { get; set; }
[DataMember]
public IEnumerable<ClassB> Lines { get; set; }
}
[DataContract]
public class ClassB
{
[DataMember]
public string UniqueId { get; set; }
[DataMember]
public string ParentId { get; set; }
[DataMember]
public Dictionary<string, ClassC> DataMapping {get; set;}
}
and ClassC is just a container of 7 ints and 1 object properties.
Still looking for something :)
EDIT 2: I reproduced the bug only using the mongoDb C# drivers 2.1.1 release version. Here is the code :
using MongoDB.Bson;
using MongoDB.Driver.Linq;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace TestingMongoDbCsharpDriver
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Debugging starting...");
try
{
MongoDB.Driver.MongoClient myClient = new MongoDB.Driver.MongoClient("mongodb://localhost:27010");
var db = myClient.GetDatabase("DocumentStoreDb");
var collection = db.GetCollection<DocumentModel>("TestOverload");
Console.WriteLine("Collection TestOverload found");
Random rand = new Random(999999999);
DocumentModel toInsert = null;
for (int lineNb = 1; lineNb < 50000; lineNb += 1000)
{
string id = rand.Next().ToString();
Console.WriteLine(string.Format("\nCreating document with id '{0}' and {1} lines...", id, lineNb));
toInsert = Funcs.Create(id, lineNb);
Console.WriteLine("Created.");
// Saving and waiting for it to finish
collection.InsertOneAsync(toInsert).Wait();
Console.WriteLine("Inserted.");
// retrieving it
var filter = new BsonDocument("_id", new BsonDocument("$eq", id));
var cursor = collection.FindAsync<DocumentModel>(filter).Result;
cursor.MoveNextAsync().Wait();
string messFilterMethod = cursor.Current.Count() == 1 ? "Retrieved" : "Not retrieved. Bug confirmed";
Console.WriteLine("With Filter: " + messFilterMethod);
var model = MongoQueryable.FirstOrDefaultAsync(collection.AsQueryable(), e => e._id == id).Result;
string mess = model != null ? "Retrieved" : "Not retrieved. Bug confirmed";
Console.WriteLine("With AsQueryable: " + mess);
// Removing it
collection.DeleteOneAsync(filter).Wait();
Console.WriteLine("Deleted.\n");
Console.ReadKey();
}
}
catch (Exception e)
{
Console.WriteLine("\n\nERROR: " + e.Message);
}
Console.WriteLine("\n\n**************** NO BUG *************\n");
}
}
public static class Funcs
{
public static DocumentModel Create(string uniqueId, int nbLines)
{
Random random = new Random(2000000);
List<MyDocumentSubElement> listOk = new List<MyDocumentSubElement>();
for (int lines = 0; lines < nbLines; ++lines)
{
Dictionary<string, SnapCellValueStyle> newDico = new Dictionary<string, SnapCellValueStyle>();
for (int i = 0; i < 10; ++i)
{
int idSnap = random.Next();
var snap = new SnapCellValueStyle()
{
alignment = idSnap,
Value = "okkkkkkkkkkzzzzkk"
};
newDico.Add("newKey_" + idSnap.ToString(), snap);
}
MyDocumentSubElement doc = new MyDocumentSubElement()
{
Icon = 516,
Name = "name du truc",
ParentId = "parent id",
type = SubElementType.T3,
UniqueId = "uniqueId_" + random.Next().ToString(),
MapColumnNameToCellValue = newDico
};
listOk.Add(doc);
}
int headerId = random.Next();
MyDocumentHeader temp = new MyDocumentHeader()
{
Comment = "comment",
Date = DateTime.Now,
ExtractionId = headerId,
Id = "id ok _ " + headerId,
Name = "Name really interesting name",
OwnerId = 95115,
RootFolioId = 51,
SnapshotViewId = MyDocumentType.Type2
};
DocumentModel toInsert = new DocumentModel()
{
_id = uniqueId,
Header = temp,
XmlMarketDates = "<xmlPrefok65464f6szf65ze4f6d2f1ergers5fvefref3e4f05e4f064z68f4xd35f8eszf40s6e40f68z4f0e8511xf340ed53f1d51zf68d4z61ef644dcdce4f64zef84zOKok>><>>",
XmlPreference = "<<zefaiunzhduiaopklzpdpakzdplapdergergfdgergekâzda4684z16ad84s2dd0486za04d68a04z8d0s1d d4az80d46az4d651s1d8 154efze40f6 4ze65f40 65ze40f6z4e>><>>>",
Lines = listOk
};
return toInsert;
}
}
// Imitation of SnapshotDocModel
[DataContract]
public class DocumentModel
{
[DataMember]
public string _id { get; set; }
[DataMember]
public MyDocumentHeader Header { get; set; }
[DataMember]
public string XmlPreference { get; set; }
[DataMember]
public string XmlMarketDates { get; set; }
[DataMember]
public IEnumerable<MyDocumentSubElement> Lines { get; set; }
}
[DataContract]
public class MyDocumentHeader
{
[DataMember]
public string Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public int OwnerId { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember]
public DateTime Date { get; set; }
[DataMember]
public int RootFolioId { get; set; }
[DataMember]
public MyDocumentType SnapshotViewId { get; set; }
[DataMember]
public int ExtractionId { get; set; }
}
[DataContract]
public class MyDocumentSubElement
{
[DataMember]
public string UniqueId { get; set; }
[DataMember]
public string ParentId { get; set; }
[DataMember]
public int Icon { get; set; }
[DataMember]
public SubElementType type { get; set; }
[DataMember]
public Dictionary<string, SnapCellValueStyle> MapColumnNameToCellValue { get; set; }
[DataMember]
public string Name { get; set; }
}
public class SnapCellValueStyle
{
public object Value { get; set; }
public int alignment { get; set; }
public int Red { get; set; }
public int Green { get; set; }
public int Blue { get; set; }
public int currency { get; set; }
public int decimalPoint { get; set; }
public int kind { get; set; }
public int style { get; set; }
}
#region enum
public enum MyDocumentType
{
Undefined,
Type1,
Type2,
Type3,
Type4,
Type5
}
public enum SubElementType
{
T1,
T2,
T3
}
#endregion
}
If you test it, you will see that there is the point where the AsQueryable method does not work anymore where as the document is still retrievable by the method using a filter.
Problem fixed in the version 2.2.4 of the c# mongo db driver (probably with the bug https://jira.mongodb.org/browse/CSHARP-1645)
Thanks :)
I have a response from Jira API, require to be deserialized into data model:
com.atlassian.greenhopper.service.sprint.Sprint#40675167[id=10151,rapidViewId=171,state=CLOSED,name=Sprint 37.1,startDate=2015-07-30T16:00:22.000+03:00,endDate=2015-08-13T16:00:00.000+03:00,completeDate=2015-08-13T14:31:34.343+03:00,sequence=10151]
This is actually the information of current sprint for issue.
I need to deserialize it to a model like:
public class Model
{
public string name { get; set; }
...
}
I have already removed all non-required information, like com.atlassian.greenhopper.service.sprint.Sprint#40675167 using Regex pattern \[(.*?)\] so I have brackets and all inside.
Now I stopped completely trying to find the a way to convert this string to a data model.
Found the following thread at the Atlassian Answers page and there appears to be no JSON representation of that inner Object. As shown in the example from that thread:
customfield_10007:[
"com.atlassian.greenhopper.service.sprint.Sprint#a29f07[rapidViewId=<null>,state=CLOSED,name=NORD - Sprint 42,startDate=2013-07-29T06:47:00.000+02:00,endDate=2013-08-11T20:47:00.000+02:00,completeDate=2013-08-14T15:31:33.157+02:00,id=107]",
"com.atlassian.greenhopper.service.sprint.Sprint#769133[rapidViewId=<null>,state=ACTIVE,name=NORD - Sprint 43,startDate=2013-08-14T15:32:47.322+02:00,endDate=2013-08-23T15:32:47.322+02:00,completeDate=<null>,id=117]"
],
The response is indeed a JSON array, but the array itself contains CSV's, so you can make use of the following to parse that:
public class DataObject
{
public string id { get; set; }
public string rapidViewId { get; set; }
public string state { get; set; }
public string name { get; set; }
public string startDate { get; set; }
public string endDate { get; set; }
public string completeDate { get; set; }
public string sequence { get; set; }
}
public class Program
{
private const string sampleStringData =
#"[id=10151,rapidViewId=171,state=CLOSED,name=Sprint 37.1,startDate=2015-07-30T16:00:22.000+03:00,endDate=2015-08-13T16:00:00.000+03:00,completeDate=2015-08-13T14:31:34.343+03:00,sequence=10151]";
static void Main(string[] args)
{
var dataObject = new DataObject();
string[][] splitted;
var sampleWithNoBrackets = sampleStringData.Substring(1,sampleStringData.Length-2);
splitted = sampleWithNoBrackets.Split(',').Select(p => p.Split('=')).ToArray();
dataObject.id = splitted[0][1];
dataObject.rapidViewId = splitted[1][1];
dataObject.state = splitted[2][1];
dataObject.name = splitted[3][1];
dataObject.startDate = splitted[4][1];
dataObject.endDate = splitted[5][1];
dataObject.completeDate = splitted[6][1];
dataObject.sequence = splitted[7][1];
Console.ReadKey();
}
}
Here's the output for the above: