c# property contains only get,where the value set from App.config - c#

I have a sample c# application.
In the App.config file there is parameters such as add key="access" value="abcd" inside appSettings tag and in other class file there is a get property such as
public string Access { get; } from where I am getting the value abcd.Here there is no set property.But I am getting the value of access as abcd and its working fine.
My question is, where the value of access in App.config is set in the application.

A readonly property still can be set from within the class that defines the property. And that's what is happening here.
Pseudo code:
public class Settings
{
private string _access;
public Settings()
{
_access = read from config;
}
public string Access { get { return _access; } }
}

Related

String Enum in C# for creating a JSON

I have a Blazor component for creating graphs with ChartJs. Based on the models, C# creates a Json for the Chart configuration. Some configurations have defined values that I can use: for example, the PointStyle accepts only few values such as circle and cross.
For this reason, I want to have the constraint to select only the accepted values for this configuration. Then, in my project I created a class PointStyle to have a sort of enum with string.
public class PointStyle
{
private PointStyle(string value) { Value = value; }
public string Value { get; private set; }
public static PointStyle Circle { get { return new PointStyle("circle"); } }
public static PointStyle Cross { get { return new PointStyle("cross"); } }
}
To obtain the correct Json configuration, in the main model I created 2 properties: PointStyle and PointStyleString.
[JsonIgnore]
public PointStyle? PointStyle {
get => _pointStyle;
set
{
_pointStyle = value;
PointStyleString = _pointStyle.Value;
}
}
private PointStyle? _pointStyle;
[JsonPropertyName("pointStyle")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string? PointStyleString { get; set; }
PointStyle accepts only the values in the defined list but this is ignored from the Json converter. For example, I can configure this like
PointStyle = PointStyle.Cross
Then, the public variable PointStyleString contains the string I have to serialize in the Json and this is updated when the PointStyle sets a new value.
Now, I have to read the property Value from the class PointStyle that contains the string I have to pass to the configuration. For this reason, I have a private variable _pointStyle that saves the value for PointStyle; so, when a new value is set, I also set the PointStyleString.
When the configuration is ready, I pass through JSRuntime the configuration like
await JSRuntime.InvokeVoidAsync("setup", Config.CanvasId, dotnet_ref, Config);
I don't know exactly how the Config is translated to the Json but the resulted Json is correct for the graph.
Everything I described above is working but it seems to me quite complicated for just setting a value. Do you think I can simplify this code?

Making json configs for applications 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.

C# json deserialiser how to set property

My code is:
namespace RTT_API
{
class routepoint
{
public string description { get; set; }
public string TIPLOC { get { return TIPLOC; } set { SetStationRef(); } }
public string publicTime { get; set; }
public Guid StationRef { get; set; }
public void SetStationRef()
{
SqlCommand comStationRef = new SqlCommand("select uniqueref from station where tiploc=#tiploc", Globals.RTTConn);
comStationRef.Parameters.Add("#tiploc");
comStationRef.Parameters["#tiploc"].Value = TIPLOC;
SqlDataReader rdrStationRef = comStationRef.ExecuteReader();
if (rdrStationRef.HasRows == true)
{
rdrStationRef.Read();
StationRef = rdrStationRef.GetGuid(1);
rdrStationRef.Close();
}
else
{
rdrStationRef.Close();
comStationRef.CommandText="Insert into station(tiploc) values (#tiploc)";
comStationRef.ExecuteNonQuery();
}
rdrStationRef.Close();
}
}
}
I would appreciate help with the following:
If I try to debug the TIPLOC value I receive a Stackoverflow error. It worked OK when the definition was only:
public string TIPLOC { get; set; }
The SetStationRef method doesn't run when the value is set
The TIPLOC value is set by a JSON deserialise command. Is using a custom 'set' method the correct way to set the StationRef value? I tried putting code in the class constructor but it looks like the constructor runs before the JSON deserialise sets the properties? I'm new to C# so trying not to get into any bad practices to start with.
Thanks
This line
public string TIPLOC { get { return TIPLOC; } set { SetStationRef(); } }
will return TIPLOC indefinitely because it is calling itself. Calling return TIPLOC will call the getter of TIPLOC and its just going to keep doing that until it overflows the stack. When you debug the debugger will try and retrieve the value of the property and will get stuck in that loop.
set { SetStationRef(); } also ignores the value. I assume you want to call SetStationRef(value);. In the setter of a property the value the user is trying to set gets passed in as a local variable called value
From the overall look I think what you are trying to achieve is something along the lines of
private string tiploc;
public string TIPLOC
{
get
{
if(tiploc == null)
{
tiplock = GetValueFromDatabase(); // Replace this to retrieve the value
}
tiploc;
}
set
{
SetStationRef(value);
tiploc = value;
}
}
My original three questions were:
If I try to debug the TIPLOC value I receive a Stackoverflow error
The SetStationRef method doesn't run when the value is set -
The TIPLOC value is set by a JSON deserialise command. Is using a custom 'set' method the correct way to set the StationRef value? I tried putting code in the class constructor but it looks like the constructor runs before the JSON deserialise sets the properties? I'm new to C# so trying not to get into any bad practices to start with.
Question 1 was answered by Ben and his help enabled me to find a solution to questions 2 and 3 so a lot of credit is due to him.
I've only added a separate answer because the custom accessor needs to be defined on the StationRef and not the Tiploc (the Tiploc is set by the Deserialisation code) as follows:
public string tiploc { get; set; }
public Guid StationRef
{
get
{
if (stationRef == Guid.Empty)
{
stationRef = Globals.GetStationRef(tiploc);
}
return stationRef;
}
set
{
stationRef = value;
}
}

Configuration.GetSection() easily gets primitive string values but not complex values

This really amazes me. I am reading values from appsettings.json using Configuration.GetSection method and in nutshell my appsettings.json looks like below:
"AppSettings":
{
"PathPrefix": "",
"Something": "Something else",
"Clients":{"foo": "bar"}
}
Now I surprises me is that if I do something like below:
var foo = Configuration.GetSection("AppSettings:Clients:foo").Value;
Then it gets the value correctly. It gets the value bar
However, when I do
var clients = Configuration.GetSection("AppSettings:Clients").Value;
it returns null. It's not only this field, whenever I call getSection method to get any complex object then it returns null but when I call it to get a basic string value then it gets the value correctly even though seeminglyi, it had problems in getting its parent element. This baffles me and raises three questions:
Why would it have issues getting complex values but not getting basic string values?
Is it by design? If so , why?
If I want to load entire object, how do I do that?
You can load an entire object using a strongly typed object.
First, create a class (or classes) to hold you settings. Based on your example this would look like:
public class AppSettings
{
public string PathPrefix { get; set; }
public string Something { get; set; }
public Clients Clients { get; set; }
}
public class Clients
{
public string foo { get; set; }
}
Now, you need to add the Options service to your service collection and load your settings from the configuration:
public void ConfigureServices(IServiceCollection services)
{
// This is only required for .NET Core 2.0
services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddMvc();
}
You now access the properties by injecting them into your class, for example:
public class HomeController : Controller
{
private readonly AppSettings _settings;
public HomeController(IOptions<AppSettings> settings)
{
_settings = settings.Value;
}
}
You can also load suboptions in the ConfigureService method by specifying the configuration section to load e.g.
services.Configure<Clients>(Configuration.GetSection("AppSettings:Clients");
Now you can inject IOptions<Clients> to access those settings
The official documentation can be found here
What would you expect it to return? You can get complex objects using the Get<T> extension method. Try this:
var clients = Configuration.GetSection("AppSettings:Clients").Get<YourClientsType>();

Why is this generic list not being saved in application settings?

I'm saving and loading various variables in my application settings file (Settings.settings). Saving/Loading variables such as strings, Uris and DataTables is working correctly.
When attempting to Save/Load a custom object List<IterationFilter>, the List is lost when the application is closed and reopened. List<IterationFilters> becomes null when the application is reloaded... even though an IterationFilter was added to the List and saved.
Saving a String (working correctly):
Properties.Settings.Default.ConnectionString = connectionString;
Properties.Settings.Default.Save();
Saving a Generic List:
Properties.Settings.Default.FilterList.Add(newFilter);
Properties.Settings.Default.Save();
I followed this answer, to create my List setting. My .settings file looks like this:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public System.Collections.Generic.List<TFS_Extraction.IterationFilter> FilterList {
get{
return ((System.Collections.Generic.List<TFS_Extraction.IterationFilter>)(this["FilterList"]));
}
set{
this["FilterList"] = value;
}
}
My IterationFilter class:
namespace TFS_Extraction
{
[Serializable]
public class IterationFilter
{
public string Operator { get; set; }
public string Value { get; set; }
public IterationFilter(string _operator, string _value)
{
Operator = _operator;
Value = _value;
}
}
TFS_Extraction.IterationFilter has to be serializable. The class is required to have a public default constructor.

Categories

Resources