I have int appsettings.js section like that:
"AccessKeys": {
"user1": {
"pass": ""
},
I created classes in C# to bind this section to these classes:
public class AccessKeys
{
public List Users = new List();
}
public class AccessKeyUserJson
{
public AccessKeyUser AccessKeyUser { get; set; }
}
public class AccessKeyUser
{
public string Pass { get; set; }
}
I bind above classes in Startup.cs:
services.Configure<AppSettingsConfig>(Configuration);
In AppSettingsConfig I have property AccessKeys and this property is binded correctly but Users is empty (0 items)
I changed structure:
"AccessKeys": [
{
"user1": "",
"pass": ""
},
]
Why don't you try something like this:
using (var ms = new System.IO.MemoryStream(Encoding.Unicode.GetBytes(myJSONstring)))
{
System.Runtime.Serialization.Json.DataContractJsonSerializer js = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(myStruct));
myStruct aux = (myStruct)js.ReadObject(ms);
}
This is a single level approach, and sincerely, I've never tried to cast anything in a sub-classing scheme but maybe it worths trying.
As you can see, here, the JSON string is taken by a Memory Stream and then casted into the final struct/class.
Related
I'm trying to learn how the lists work and I'm quite lost on a concept of using set; get; properties and working with a List. I have a project that I want to populate a list with 2 items that are related to each other (hence a object) Relation and an ID so I created a RelationLink class, the idea is to populate list with these 2 prosperities but using (get; set;) and I'm not quite sure how to do this so it would let me add the properties to a list and retrive a list from a PropertiesRepository as well.
public class PropertiesRepository
{
public class RelationLink
{
public string Relation { get; set; }
public string LinkID { get; set; }
}
public class ListofRelations
{
public List<RelationLink> relList { get; set; }
public void addRelation(RelationLink rel)
{
relList.Add(rel);
}
}
}
the code below fails at listofRelations.addRelation(relationLink) when debugging I can see that its going to add addRelation method and I see the values being passed. However when adding the object to a list nothing is being added. so when get runs it fails due to null exception.
am I doing the setters getters correctly? the part where I'm lost is how can I add the 2 (string) properties to that list in a main program file with setters, that could be read from relList
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
PropertiesRepository repProperties = new PropertiesRepository();
PropertiesRepository.RelationLink relationLink = new PropertiesRepository.RelationLink();
PropertiesRepository.ListofRelations listofRelations = new PropertiesRepository.ListofRelations();
relationLink.Relation = "Relation A";
relationLink.LinkID = "12345";
listofRelations.addRelation(relationLink);
foreach (var elm in listofRelations.relList)
{
Console.WriteLine("Relation from List is " + elm.Relation + "Link ID from List is " + elm.LinkID);
}
}
}
relList in your instance of listofRelations is never initialised with an instance of the list.
public class ListofRelations
{
public List<RelationLink> relList { get; set; } = new List<RelationLink>();
public void addRelation(RelationLink rel)
{
relList.Add(rel);
}
}
you could initialise it like this or in a constructor. Or before you call addRelation you could write if you want.
listOfRelations.relList = new List<RelationLink>();
I have a MongoDB document with a settings field, itself with two nested fields, selectedSectionIds and sectionColors. settings is not an array. I need to update only the selectedSectionIds field.
My update builder looks like this:
Builders<Account>.Update.Set(
"settings.selectedSectionIds",
sectionIds)
And I'm calling UpdateOneAsync with nothing more special.
When settings is not present in the original document or already contains something, all works well, but when settings is null (and it can), I get the following MongoWriteException:
A write operation resulted in an error.
cannot use the part (settings of settings.selectedSectionIds) to traverse the element ({settings: null})
How can I update my builder (or class maps/serializers?) to support all scenarios?
(MongoDB C# drivers 2.8)
you cannot update a property of a null. if it was an empty object {} it would work.
so my suggestion is to do a bulk update command with 2 steps. where in the first step you check for the null and change it, and in the second step you set the sub property value as needed.
here's an example using MongoDB.Entities for brevity:
using MongoDB.Entities;
namespace StackOverflow
{
public class Program
{
public class Account : Entity
{
public string Name { get; set; }
public Settings Settings { get; set; }
}
public class Settings
{
public string[] SelectedSectionIDs { get; set; }
public string[] SectionColors { get; set; }
}
private static void Main(string[] args)
{
new DB("test", "127.0.0.1");
var acc1 = new Account
{
Name = "Account One",
Settings = new Settings
{
SectionColors = new[] { "green", "red" },
SelectedSectionIDs = new[] { "xxx", "yyy" }
}
}; acc1.Save();
var acc2 = new Account
{
Name = "Account Two",
Settings = null
}; acc2.Save();
DB.Update<Account>()
.Match(a => a.Settings == null)
.Modify(a => a.Settings, new Settings())
.AddToQueue()
.Match(_ => true)
.Modify(a => a.Settings.SelectedSectionIDs, new[] { "aaa", "bbb" })
.AddToQueue()
.Execute();
}
}
}
I'm in the process of learning C# and now trying to learn how to work with JSON objects. For the purpose of that I'm writing a quiz game. I have managed to console writeline the content of simple JSON objects, but when they are more complex I only can log the object name. Example is shown below in the code.
The JSON object:
{
"QuestionId": "1",
"QuestionString": "What is blue?",
"Options": [
{
"Option": "The sky",
"Correct": false
},
{
"Option": "The limit",
"Correct": false
},
{
"Option": "A color",
"Correct": true
}
]
}
The class:
{
public class OptionType
{
public OptionType()
{
}
public string Option { get; set; }
public bool Correct { get; set; }
}
public class Question
{
public Question()
{
}
public string QuestionId { get; set; }
public string QuestionString { get; set; }
public List<OptionType> Options { get; set; }
}
}
And the code:
string fileName = #"C:\QuizGame\QuestionAnswer.json";
string jsonTxt = string.Empty;
using (StreamReader r = new StreamReader(fileName))
{
var json = r.ReadToEnd();
jsonTxt = json.ToString();
}
var question = JsonConvert.DeserializeObject<Question>(jsonTxt);
Console.WriteLine(question.Question)
// prints "What is blue?" // works like a charm
Console.WriteLine(question.OptionType)
// prints "System.Generic.List`1[QuizGame.OptionType]"
// and if I do a foreach:
foreach (object o in question.Options)
{
Console.WriteLine(o);
}
// prints QuizGame.OptionType x 3
My expected result is to be able to print the options for the question. It seems like at least something in the code is working since I'm able to see that there are 3 options for answer, so I guess it's something with my understanding of object oriented code / C# that is missing. Thankful for all replies.
Solved: I changed the "object" keyword to "var" (or "OptionType") and could then get to my nested objects. I've struggled for days with this. I googled and tried new things base on your input, so thanks alot!
foreach (var o in question.Options)
{
Console.WriteLine(o.Option); // loops through "Options"
Console.WriteLine(o.Correct); // loops through "Correct"
}
You are trying to print out a List. If you just want to print out all information then you maybe just want to add another foreach in your foreach-loop. Maybe sth. like this:
foreach (object o in question.Options)
{
foreach (object ob in o)
{
Console.WriteLine(ob.ToString());
}
}
But there are better approaches for that. You could for example override the ToString()-Method in your model-class and just call question.ToString().
I'm using datatables.net for ASP.NET MVC and I would like to create a class names DataTablesConfiguration that contains all properties of datatables.net. The purpose of this is instead config properties of datatables in View or JS file, I can config by setting properties of a DataTablesConfiguration object in server-side code, and then serialize the object to json object and pass into View. So all config of datatables would be done on server-side.
Example:
I can do like that to config datatables:
DataTablesConfiguration config = new DataTablesConfiguration();
config.ServerSide = true;
config.Ajax.Url = "/Demo/LoadData";
config.Columns.Add(new DataTablesColumn
{
Data = "CustomerID",
AutoWidth = true,
Header= "CustomerID",
Name = "CustomerID"
});
The problem is:
Datatables has many properties with dynamic type. Example:
autoFill:
Maybe this:
$('#myTable').DataTable( {
autoFill: true
} );
But sometimes:
$('#myTable').DataTable( {
autoFill: {
alwaysAsk: true,
columns: ':not(:last-child)'
}
} );
And sometimes:
$('#myTable').DataTable( {
autoFill: {
alwaysAsk: true,
columns: [0,1,2],
enable: true
}
} );
buttons:
Maybe this:
$('#myTable').DataTable( {
buttons: [
'copy', 'excel', 'pdf'
]
} );
But some time:
$('#myTable').DataTable( {
buttons: [
{
extend: 'copy',
text: '<u>C</u>opy',
key: {
key: 'c',
altKey: true
},
//and some other properties may appear here based on extend
property
}
]
} );
I mean properties in datatables config is dynamic. So how to describe them by Class in C# code and able then serialize it to what datatables exactly wants to receive.
I tried this:
public class DataTablesConfiguration
{
//Init default values base on datatables.net's reference
public DataTablesConfiguration()
{
this.Buttons = new List<ButtonOption>();
}
[JsonProperty(PropertyName = "buttons")]
public ICollection<ButtonOption> Buttons { get; set; }
public string GetJsonConfig()
{
return JsonConvert.SerializeObject(this);
}
}
public class ButtonOption
{
public ButtonOption(string extend, string text)
{
this.Extend = extend;
this.Text = text;
}
[JsonProperty(PropertyName = "extend")]
public string Extend { get; set; }
[JsonProperty(PropertyName = "text")]
public string Text { get; set; }
//How can I define all other properties here
}
But it seems to be not a good approach. Is there any better approach to make datatables could be configured on server-side code?
If I have a class like this:
[DataContract(Name = "", Namespace = "")]
public class MyDataObject
{
[DataMember(Name = "NeverNull")]
public IList<int> MyInts { get; set; }
}
Is there a way I can make MyInts field a non-null empty list when the following string is deserialized?
string serialized = #"{""NeverNull"":null}";
MyDataObject myDataObject = JsonConvert.DeserializeObject<MyDataObject>(serialized);
I’m using Newtonsoft.Json
The reason I ask is that I have a fairly complicated json request to parse, it contains nests of lists of objects and I'd like the deserialization code to create these object so I can avoid lots of null checks:
if (foo.bar != null)
{
foreach (var bar in foo.bar)
{
if (bar.baz != null)
{
foreach (var baz in bar.baz)
{
...
Perhaps add a post-serialization callback that checks this at the end of deserialization?
[DataContract(Name = "", Namespace = "")]
public class MyDataObject
{
[OnDeserialized]
public void OnDeserialized(StreamingContext context)
{
if (MyInts == null) MyInts = new List<int>();
}
[DataMember(Name = "NeverNull")]
public IList<int> MyInts { get; set; }
}
Note also that JsonConvert (unlike DataContractSerializer) executes the default constructor, so usually you could also have just added a default constructor:
public MyDataObject()
{
MyInts = new List<int>();
}
however, in this case the explict "NeverNull":null changes it back to null during deserialization, hence why I've used a callback above instead.
Initialization of IList<int>with new int[0] will help you out!
Its the solution that gives me the best results.