Making json configs for applications c# - c#

i need a config file for my applications and i've looked through internet without really finding what I want, I want to set my config to a var and use it like config.somethingInTheConfig.
I tried some things but it didn't work,
the config file :
{
"id": 00,
"somethings": true,
"yes": "idkjustsomething"
}
the Config class :
class Config
{
public static int id { get; set; }
public static bool somethings { get; set; }
public static string yes { get; set; }
}
Code to read it
using (StreamReader streamReader = new StreamReader("config.json"))
{
string json = streamReader.ReadToEnd();
Config config = JsonConvert.DeserializeObject<Config>(json);
Console.WriteLine(config.id);
}
I want it to show the id in the config in the console but it doesn't work nd gives me an error, anyone could help ?

The properties are marked static.
JsonConvert will not be able to read values into the static properties.
And since you are not defining values for them at design time, the properties will be set to their default values unless you manually change them.

Related

Configuration.GetSection in Asp.Net Core 2.0 getting all settings

I am trying to learn the various ways to retrieve configuration info so I can determine the best path for setting up and using configuration for an upcoming project.
I can access the various single settings using
var sm = new SmsSettings
{
FromPhone = Configuration.GetValue<string>("SmsSettings:FromPhone"),
StartMessagePart = Configuration.GetValue<string>("SmsSettings:StartMessagePart"),
EndMessagePart = Configuration.GetValue<string>("SmsSettings:EndMessagePart")
};
I also need to be able to count settings, determine values of certain settings etc. So I was building a parsing method to do these types of things and needed a whole section of the settings file, which is what I assumed GetSection did.
Wrong.
appsettings.json :
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=TestingConfigurationNetCoreTwo;Trusted_Connection=True;MultipleActiveResultSets=true",
"ProductionConnection": "Server=(localdb)\\mssqllocaldb;Database=TestingConfigurationNetCoreTwo_Production;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"SmsSettings": {
"FromPhone": "9145670987",
"StartMessagePart": "Dear user, You have requested info from us on starting",
"EndMessagePart": "Thank you."
}
}
This code:
var section = Configuration.GetSection("ConnectionStrings");
Returns these results:
A few questions arise.
Why is this returning 3 different JsonConfigurationProviders, one of which includes every setting in the appsettings.json file (shown in Image 2)
Why isn't GetSection("ConnectionStrings") actuall doing just that, returning the sub children of the ConnectionStrings
Given number 2, how do you actually just retrieve the children of ConnectionStrings ?
Assuming a model ConnectionStrings, with one property, List Connections, can the section be converted to an object?
I understand the answer has been accepted. However, providing proper example code, just in case anyone looking to understand a bit more...
It is quite straight forward to bind custom strong type configuration. ie. configuration json looks like below
{
"AppSettings": {
"v": true,
"SmsSettings": {
"FromPhone": "9145670987",
"StartMessagePart": "Dear user, You have requested info from us on starting",
"EndMessagePart": "Thank you."
},
"Auth2Keys": {
"Google": {
"ClientId": "",
"ClientSecret": ""
},
"Microsoft": {
"ClientId": "",
"ClientSecret": ""
},
"JWT": {
"SecretKey": "",
"Issuer": ""
}
}
}
}
and your C# classes looks like
public class SmsSettings{
public string FromPhone { get; set;}
public string StartMessagePart { get; set;}
public string EndMessagePart { get; set;}
}
public class ClientSecretKeys
{
public string ClientId { get; set; }
public string ClientSecret { get; set; }
}
public class JWTKeys
{
public string SecretKey { get; set; }
public string Issuer { get; set; }
}
public class Auth2Keys
{
public ClientSecretKeys Google { get; set; }
public ClientSecretKeys Microsoft { get; set; }
public JWTKeys JWT { get; set; }
}
You can get the section by GetSection("sectionNameWithPath") and then Convert to strong type by calling Get<T>();
var smsSettings = Configuration.GetSection("AppSettings:SmsSettings").Get<SmsSettings>();
var auth2Keys= Configuration.GetSection("AppSettings:Auth2Keys").Get<Auth2Keys>();
For simple string values
var isDebugMode = Configuration.GetValue("AppSettings:IsDebugMode");
Hope this helps...
according to this post
https://github.com/aspnet/Configuration/issues/716
the GetSection("Name").Value will return null, you must use GetChildren to get the child items
Bind will populate the properties aginst the provided object, by default it maps against public properties, look at the update to support private properties.
try Get<T>() over bind, it will provide you a strongly typed instance of the configuration object
try a simple POCO of your class (no complex getter/setters, all public, no methods) and then take it from there
Update:
From .net core 2.1 BindNonPublicProperties added to BinderOptions, so if set to true (default is false) the binder will attempt to set all non read-only properties.
var yourPoco = new PocoClass();
Configuration.GetSection("SectionName").Bind(yourPoco, c => c.BindNonPublicProperties = true)
If you use GetSections() along with Bind() you should be able to create poco objects for your use.
var poco= new PocoClass();
Configuration.GetSection("SmsSettings").Bind(poco);
This should return to you a poco object with all the values set.
If you use the Bind method on the object returned by GetSection, then this would bind the key value pairs within the section to corresponding properties of the object it has been bound too.
For example,
class ConnectionStrings {
public string DefaultConnection { get; set;}
public string ProductionConnection {get; set;}
}
..
var connectionStrings = new ConnectionStrings();
var section = Configuration.GetSection("ConnectionStrings").Bind(connectionStrings);
It works for me on .Net Core directly on Razor HTML:
#Html.Raw(Configuration.GetSection("ConnectionStrings")["DefaultConnectoin"]) <!-- 2 levels -->
#Html.Raw(Configuration.GetSection("Logging")["LogLevel:Default"]) <!-- 3 levels -->
#Html.Raw(Configuration.GetSection("SmsSettings")["EndMessagePart"]) <!-- 2 levels -->
Reference:
https://www.red-gate.com/simple-talk/dotnet/net-development/asp-net-core-3-0-configuration-factsheet/
If you required any section with "GetSection" and (key,value), try this:
Configuration.GetSection("sectionName").GetChildren().ToList()
and get a Collection of keys with vallues, can manipulate with LinQ

C# Dynamically make settings within application then save persistently

I am finding a lot of different ways to do this and I'm not sure the direction I should go...
I have an application that will run on several personal computers. I am looking for a way to keep a list of application settings persistently.
The idea being that the user will be able to choose amongst a list of applications. Those applications will then be saved until the user removes them. I need to save the application name and the corresponding path.
The problem is that I can't seem to save the key, value pairs to new settings in visual studio and have them persist. I need to write a file to save the files, how do I go about doing that... Should I write them to system.configuration, JSON or XML??? Does anyone have a good walkthrough?
Well, there are a lot of ways to do that. For a simple approach, you can use XML serialization. First create a class that represents all the settings you want to save, and add the Serializable attribute to it, for example:
[Serializable]
public class AppSettings
{
public List<UserApp> Applications { get; set; }
}
[Serializable]
public class UserApp
{
public string Path { get; set; }
public string Name { get; set; }
}
Then, add the following methods to it:
public static void Save(AppSettings settings)
{
string xmlText = string.Empty;
var xs = new XmlSerializer(settings.GetType());
using (var xml = new StringWriter())
{
xs.Serialize(xml, settings);
xml.Flush();
xmlText = xml.ToString();
}
string roamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
File.WriteAllText(roamingPath + #"\settings.xml", xmlText);
}
public static AppSettings Load()
{
string roamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
if (!File.Exists(roamingPath + #"\settings.xml"))
return new AppSettings();
string xmlText = File.ReadAllText(roamingPath + #"\settings.xml");
var xs = new XmlSerializer(typeof(AppSettings));
return (AppSettings)xs.Deserialize(new StringReader(xmlText));
}
Then, to save, do:
AppSettings settings = new AppSettings();
settings.Applications = new List<UserApp>();
settings.Applications.Add(new UserApp { Path = #"C:\bla\foo.exe", Name = "foo" });
AppSettings.Save(settings);
And to load:
AppSettings settings = AppSettings.Load();
You can also edit the loaded settings and save it again, overwriting the older.
For more a more complex approach, save into a database.
Add a setting to the settings using the instructions shown in below screenshot:
NOTE: Double click Properties shown with first arrow.
Then you can update that value at runtime like this:
namespace ConsoleApplication1
{
public class Program
{
public static void Main()
{
var defSettings = ConsoleApplication1.Properties.Settings.Default;
var props = defSettings.Test = "Whatever";
// Save it so it persists between application start-ups
defSettings.Save();
Console.Read();
}
}
}
The settings will be stored in the user's profile.

How to retrieve property from GameSparks inside Unity

I am going crazy... I am missing something and I can't see what?!?!
I have created a property called "GAME_SETTINGS" inside the gameSparks admin area and have included this in it:
{
"AppVersionIOS": 1,
"AppVersionAndroid": 1
}
I am then trying to retrieve it inside Unity like this:
new GameSparks.Api.Requests.GetPropertyRequest().SetPropertyShortCode("GAME_SETTINGS").Send((response) => {
if (!response.HasErrors) {
Debug.Log("Setting Achieved: "+response.JSONString);
} else {
Debug.Log("Error Getting Settings");
}
});
I can see that I am getting the settings in my Debug.Log:
Setting Achieved: {"#class":".GetPropertyResponse","property":{"AppVersionIOS":1,"AppVersionAndroid":1},"requestId":"XXXXXXXXXXXXXXX","scriptData":null}
My question is though... How do I get the properties AppVersionIOS and AppVersionAndroid inside an Dictionary so I can call on them from other scripts...
Really hoping for help in this matter and thanks in advance :-)
I actually work for GameSparks and noticed your question so set up an account to answer you.
The property values returned in the JSON are of nullable type : https://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx
Best practice is to parse the values before they are cached in a Dictionary or otherwise.
The following code should allow you to get those properties, then you may store them in a dictionary as you see fit.
public void GetProperties()
{
new GameSparks.Api.Requests.GetPropertyRequest()
.SetPropertyShortCode("GAME_SETTINGS")
.Send((response) =>
{
if (!response.HasErrors)
{
print(response.JSONString);
int androidProperty = (int)response.Property.GetInt("AppVersionAndroid");
int IOSProperty = (int)response.Property.GetInt("AppVersionIOS");
print("AndroidProperty:" + androidProperty);
print("IOSProperty:" + IOSProperty);
}
else
{
Debug.LogWarning(response.JSONString);
}
});
}
Hopefully this solves your problem. If you have any other questions please feel free to head to our website and log a ticket with us.
Regards, Patrick.
Notice: This answer assumes that the API doesn't have a way of converting this into a nice object which you can easily manipulate / parse, so it converts it itself using some class. It's however very likely that your API offers such a function somewhere, so you'd be better be looking in the documentation again. I guess it's somewhere near https://api.gamesparks.net/#getpropertyrequest .
You have the JSON document already, all you have to do is parse it. That'd be easier in a JavaScript file than in C#, but you can also use the JsonUtils class there, see http://docs.unity3d.com/Manual/JSONSerialization.html . Let http://json2csharp.com/ convert that JSON to a class layout for you and you get
public class Property
{
public int AppVersionIOS { get; set; }
public int AppVersionAndroid { get; set; }
}
public class RootObject
{
public string __invalid_name__#class { get; set; }
public Property property { get; set; }
public string requestId { get; set; }
public object scriptData { get; set; }
}
Now just take the string and serialize it into an RootObject.
new GameSparks.Api.Requests.GetPropertyRequest().SetPropertyShortCode("GAME_SETTINGS").Send((response) => {
if (!response.HasErrors) {
Debug.Log("Setting Achieved: "+response.JSONString);
//Serialization
var info = JsonUtility.FromJson<RootObject>(response.JSONString);
//Print the AppVersionIOS property
Debug.Log("App Version iOS: " + info.Property.AppVersionIOS);
} else {
Debug.Log("Error Getting Settings");
}
});
You might need some mofication in the data types of your class (e.g. make object scriptData to string scriptData if there can be an actual string in it), but that should be it. Have fun.

WCF MessageHeaderArray not working correctly

I have a relatively simple service that takes in a Message contract for uploading a file. Because it is a file upload, only the file stream can be in the message body so I am using the message header for meta data.
My problem is that although I've added a string[] as a MessageHeaderArray when I add a service reference to the service in a test web app client, the variable has been generated as just a string.
Here is part of my MessageContract:
[MessageContract]
public class FileInformation : IDisposable
{
[MessageHeader(MustUnderstand = true)]
public string FileName { get; set; }
[MessageHeaderArray]
public string[] RequiredEntityNames { get; set; }
[MessageHeaderArray]
public string[] RequiredEntityIds { get; set; }
[MessageHeader(MustUnderstand = true)]
public string EntityName { get; set; }
This is driving me mad and I have spent almost a day trying to figure out what's going on. Any ideas on why the RequiredEntityNames and RequiredEntityIds are being generated as string instead of string[]?
Have you tried with "MessageHeader" attribute on arrays instead of "MessageHeaderArray" ?
MSDN, "Using Arrays Inside Message Contracts" : http://msdn.microsoft.com/en-us/library/ms730255.aspx

custom Serialize Class to JSon - for really small data

well,
i have a really simple class:
public class Channel : IContent
{
public Guid Guid { get; set; }
public string Title { get; set; }
public string Alias { get; set; }
public void Set()
{
// SAVE JSON DATA
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(string.Join("", this.Guid, ".jsv")))
{
writer.Write("{ \"Title\":", this.Title, "}");
}
}
}
Serializing i could do as shown in code,
but how can i load that back into the class? that is the actual question.
please dont refer me to JavaScriptSerializer or DataContracts etc...
again, this should be so simple... that i dont think i need all those.
Json.NET. No, seriously you need a JSON serializer. Just pick one that you like. The 3 that have been listed work great. And make sure you read this article to better understand why you need a JSON serializer.

Categories

Resources