I have a windows app that uses SettingsProvider to read configuration settings and sets default values if file does not exist.
It works fine running normally.
I am trying to write a windows service that starts this app. When it is run by the service, I get System.Configuration.SettingsPropertyNotFoundException on all the setting attributes.
How can I resolve this exception when the service is running the app?
This simply means that the app can't read the .Settings file. I can think of two possible causes:
The service runs under an account that doesn't have access to the .settings file. (or .config file, depending) This is unlikely because the service can start the app, and it wouldn't make sense for it to have permissions to the app and not the settings file.
The runtime can't find the settings file. It expects the settings to be in the root startup path of the executable. Check to ensure that it exists on the machine in question.
However, a google result turned up an obvious possible cause I haven't thought of. Were the .settings added after the last compile? Compile the app in Visual Studio, and try again...
Another possible cause is if you write a custom SettingsProvider that is throwing and exception during Initialize.
In my case, I had done this:
public class CustomSettingsProvider : SettingsProvider
{
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name, config);
}
}
Since name is always passed as null, base.Initialize was throwing an ArgumentNullException. I fixed it by passing a non-null name like this:
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name ?? GetType().Name, config);
}
In my case, the profile <configSource="Profile.config" /> code was commented out in the Web.config file.
Uncommenting the above line worked for me.
Related
I am working on a .net core project, I wanted to change the connectionstring of the database in appsettings.json.
I had created a duplicate database and named it originalname_fake01 and made a clone of the original database for testing.
I have also changed the database name in appsettings.developement.json. Everything seems fine but when I run the application in debug mode in visual studio. the data was being pulled from the original database rather than the changed database name in appsettings.json.
Here is my appsettings connectionstrings code:
Old connectionstring was
"connectionStrings": {
"MyConnectionString":
"Server=localhost;port=3306;database=mydb;user=root;password=rt123;"
}
changed connection string (new)
"connectionStrings": {
"FakeConnectionString":
"Server=localhost;port=3306;database=mydb_fake01;user=root;password=rt123;"
}
I am not able to understand why it is connecting to the old database rather than the new database even after changing the connectionstring.
Any help would be appreciated.
If you want the development settings to override the production settings you need to use the same names and full path. Your connection string should be named MyConnectionString, not MyConnectionString if you want the DbContext to pick it automatically.
JSON setting files have no special meaning in .NET Core, they are just files. Every provider produces key/value pairs in the form Section1:Subsection1:Attribute1, Value. Newer provider values override earlier values. Providers can be JSON or XML file readers, INI file readers, databases etc. In all cases, the settings are flattened to path/value pairs.
The file
"connectionStrings": {
"MyConnectionString": "Server=localhost;port=3306;database=mydb;user=root;password=rt123;"
}
Produces a value named connectionStrings:MyConnectionString whose value is Server=localhost;port=3306;database=mydb;user=root;password=rt123;. To override this you need to specify a setting with the same path.
The default Host builder specifies some default settings providers. From the docs, those are :
appsettings.json.
appsettings.{Environment}.json.
= Secret Manager when the app runs in the Development environment.
Environment variables.
Command-line arguments.
Settings specified lower down the list override previous ones. This means that on a development machine, the connectionStrings:MyConnectionString in appsettings.Developoment.json overrides the element with the same name in appsettings.json.
This also means that we can override the connection string with an environment variabl or a command-line argument, eg
dotnet run /connectionStrings:MyConnectionString Server=localhost;port=3306;database=mydb;user=root;password=rt123;
I have finally able to find the problem in the dbcontext.cs modelbuilder. There is a code line which has strongly typed Schema Name.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
OnModelCreatingImpl(modelBuilder);
modelBuilder.HasDefaultSchema("MyDB");
}
I changed it use the new schema as below:
modelBuilder.HasDefaultSchema("MyDB_Fake01");
I don't understand why we need to give schema name in both connectionstring and in modelbuilder. I Guess we should avoid explicit schema name targeting in ModelBuilder so that, whenever the connectionstring is changed. it will target the database correctly.
Anyways, the problem is solved as the application is connecting to the intended database.
You are almost there. In your changed connection string (new) setting, change the FakeConnectionString to MyConnectionString. If you have same keys in appsettings.json and in appsettings.development.json then latter will override the former.
"connectionStrings": {
"MyConnectionString": "Server=localhost;port=3306;database=mydb_fake01;user=root;password=rt123;"
}
P.S. This is applicable to any environment not only to development
There is also a file named "secrets.json" which overrides all other appSettings configuration. Make sure it has correct Database name.
The file named "secrets.json" worked for me as the default connection string was hardcoded there pointing to the old database. Editing the connection string (Initial Catalog=dbName) to point to the current database name fixed the problem. Thanks!
sample content of "secrets.jason":
{
"ConnectionStrings:DefaultConnection": "Data Source=TestSource;Initial Catalog=dbName;Integrated Security=True;MultipleActiveResultSets=True"
}
I need to propagate connection string changes for entity framework, asp.net membership (which are both in the connectionstrings section of web.config) and session state (which is in sessonstate's sqlconnectionstring) in web.config when I adjust these settings in windows azure's service configuration.
During development we test our app as a standard asp.net webforms app, but once it is deployed it is running in azure. So we need to allow for the site running in both non-azure and an azure context. That's why we're just relying upon the values in web.config for now.Since these connection strings are not called directly in my code writing a utility class which grabs from azure service config if that is available or otherwise grabs from web.config is not a possibility for these values.
I realize that editing web.config would cause a disruption in service - and i only plan to do this during off hours.
I believe that the best approach is to wrap your configuration information in a service. Then, in the service, use RoleEnvironment to determine which settings to use. For example
public static class Config
{
public static string ConnStr
{
get
{
if (RoleEnvironment.IsAvailable)
return RoleEnvironment.GetConfigurationSettingValue("ConnStr");
return ConfigurationManager.AppSettings["ConnStr"];
}
}
}
If that doesn't work, and you need to change the actual web.config (for instance, using named connection strings), then you'll need to modify the config at runtime. In your role start, do something like the following:
var config = WebConfigurationManager.OpenWebConfiguration(null);
var connStrs = WebConfigurationManager.OpenWebConfiguration(null).GetSection("connectionStrings") as ConnectionStringsSection;
connStrs.ConnectionStrings["ConnStr"].ConnectionString = RoleEnvironment.GetConfigurationSettingValue("ConnStr");
config.Save();
To handle when the configuration changes after the role is running, just call the same code as above from the RoleEnvironment.Changing event.
Good luck,
Erick
What kind of permission needs to be given to the Error.log file in the server (running IIS 7.5) so that errors are written to the Error.log file?
I have created a directory named ErrorLog and set up the listener in web.config like below.
The windows identity in play (depends on how you authenticate)
var principal = ClaimsPrincipal.Current; //normally this reverts to Thread.CurrentPrincipal, but can be changed
return principal.Identity.Name;
or
var windowsIdentity = WindowsIdentity.GetCurrent();
if (windowsIdentity != null)
{
return windowsIdentity.Name;
}
The Executing windows identity Will need create permission in directory and write permission to the file specified in your EL config.
You can place file anywhere you like using config. Default for file without path is Start project directory containing assembly dll.
See In IIS the Application Pool used by the website. The pool determines the windows Identity. See the advanced settings tab for the Pool. The identity approach to be used is defined here.
I don't see your configuration example, but..
I find that it is best not to use Flat File outside of development. The Event Log or Database listeners are more suitable for a web application in production.
If you must use Flat File, you will need to give the account (for the application pool that is assigned to the web application) write access to the directory that the file should be created in. By default I think that is the web application's bin directory, unless you include a path in the file name in your configuration.
It probably depends on what context your app in operating in. The app pool thread is responsible for writing the log so give the read/write folder permissions for the same identity as your app pool. I think this is NETWORKSERVICE by default.
I have a jar that must be imported in the client application and enable the client to call my https wsdl web service with the help of the imported jar.
I see that when https service must be called, it must be a valid cacert file in the security folder of < java_home > location.
However I cannot make it possible to install the cacert file into clients javahome security folder just by only importing the jar to client's application.
If you have an idea about how to achieve this, any help would be appriciated, thanks in advance.
EDIT [SOLVED]:
I have solved my problem by adding this method just before the service call
public static void trustStore() {
Properties systemProps = System.getProperties();
systemProps.put("javax.net.ssl.trustStore","jssecacerts");
System.setProperties(systemProps);
}
EDIT [SOLVED]: I have solved my problem by adding this method just before the service call
public static void trustStore() { Properties systemProps = System.getProperties();
systemProps.put("javax.net.ssl.trustStore","jssecacerts");
System.setProperties(systemProps); }
You have two choices:
Provide instructions or an installer to the user that uses the keytool to import your certificate
Add the option "-Djavax.net.ssl.trustStore=..." to the command that boots your client application.
I am trying to have the server read from a file, called "config.txt", in the same directory as the main .html file within the war.
In hosted mode, I can easily access the file using a Scanner object:
Scanner s = new Scanner("config.txt");
But this does not work when deployed because the file paths are somehow different. How can I get the correct file path to access config.txt in the deployed version?
I have tried getServletContext.getRealPath("config.txt"), but for some reason I get a Null Pointer Exception when I attempt to call this in the ServiceImpl's constructor...
It seems like getServletContext.getRealPath("/") is the way to go, but you just can't call the method within the constructor of the server implementation.
The way I eventually got around it was by calling it when the client first made its connection.