C# Dynamically added Setting not saved - c#

I am trying to add settings to Settings file dynamically. I use code below:
public PathSourceDir(int id)
{
InitializeComponent();
_id = id;
SettingsProperty property = new SettingsProperty(Properties.Settings.Default.Properties["baseSetting"]);
property.Name = "dynamicSettingName" + _id.ToString();
property.DefaultValue = _id.ToString();
Properties.Settings.Default.Properties.Add(property);
Properties.Settings.Default.Save();
//Read stored value
var dynamicSetting = Properties.Settings.Default["dynamicSettingName" + _id.ToString()];
}
Code runs, however if I comment code lines where new property is created and Settings are saved, and run again, I get an exception:
System.Configuration.SettingsPropertyNotFoundException: 'The settings
property 'dynamicSettingName6' was not found.
Meaning that setting previously was not saved in the file. However code was executed before also with id=6. Could you please advise what is wrong?

Related

How to Create New User Setting in app.config at Run Time

I have an Editable ComboBox. The user enters text and presses a Save button. Their text is turned into a string.
I need it at Run Time to Create a new User Setting to the app.config with the name of their string. (I think this part works now).
Then another ComboBox's Selected Item is saved to the Setting. (Object reference not set error).
This is to create a custom preset that will save each control state, checkboxes, textboxes, etc. in the program.
// Control State to be Saved to Setting
Object comboBox2Item = ComboBox2.SelectedItem;
// User Custom Text
string customText = ComboBox1.Text;
// Create New User Setting
var propertyCustom = new SettingsProperty(customText);
propertyCustom.Name = customText;
propertyCustom.PropertyType = typeof(string);
Settings.Default.Properties.Add(propertyCustom);
// Add a Control State (string) to the Setting
Settings.Default[customText] = (string)comboBox2Item;
At this part I get an error.
Settings.Default[customText] = (string)comboBox2Item;
Exception:Thrown: "Object reference not set to an instance of an object."
I have tried setting ComboBox1.Text to an Object instead of string, with same error. The text and string is also not null.
Object customText = ComboBox1.Text;
Here's a visual of what I'm trying to do
Original Answer:
I haven't tried adding a new setting to the file but i have had to update it. Here is some code that I use to save and retrieve the saved changes to the file. I know it doesn't directly answer the question but should point you in the right direction as to what classes to look at and use.
I'll try to update to directly answer this question once I get some breathing time.
public static void UpdateConfig(string setting, string value, bool isUserSetting = false)
{
var assemblyPath = AppDomain.CurrentDomain.BaseDirectory;
var assemblyName = "AssemblyName";
//need to modify the configuration file, launch the server with those settings.
var config =
ConfigurationManager.OpenExeConfiguration(string.Format("{0}\\{1}.exe", assemblyPath, "AssemblyName"));
//config.AppSettings.Settings["Setting"].Value = "false";
var getSection = config.GetSection("applicationSettings");
Console.WriteLine(getSection);
var settingsGroup = isUserSetting
? config.SectionGroups["userSettings"]
: config.SectionGroups["applicationSettings"];
var settings =
settingsGroup.Sections[string.Format("{0}.Properties.Settings", assemblyName)] as ClientSettingsSection;
var settingsElement = settings.Settings.Get(setting);
settings.Settings.Remove(settingsElement);
settingsElement.Value.ValueXml.InnerText = value;
settings.Settings.Add(settingsElement);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
Edited Answer:
I did a quick google search and found an accepted answer on the MSDN forum.MSDN question. You have to call save on the properties class in order for the add to take affect. Think of a database transaction, until you call commit, it doesn't take effect.
So what appears to be missing in your code is: Properties.Settings.Default.Save(); which should be the very next line after your Settings.Default.Properties.Add(propertyCustom);

How to set Publish Date in Word Document using OpenXML

I have a situation where a user can upload a word document which contains placeholders for certain properties (i.e. in MS Word the user has gone to Insert > Quick Parts > Document Properties and chosen a property). The specific properties I want to support are Title, Author, Company and Publish Date.
Title and Author are set as Package Properties, and Company is set as an Extended File Property. These are set with the below code, which works correctly:
private static void SetDocumentProperties(ReportTemplateModel model, WordprocessingDocument wordDocument)
{
//these properties always exist
wordDocument.PackageProperties.Title = model.Title;
wordDocument.PackageProperties.Creator = model.Author;
wordDocument.PackageProperties.Created = DateTime.Now;
wordDocument.PackageProperties.Modified = DateTime.Now;
//these properties can be null
if (wordDocument.ExtendedFilePropertiesPart == null)
{
wordDocument.AddNewPart<ExtendedFilePropertiesPart>();
}
if (wordDocument.ExtendedFilePropertiesPart.Properties == null)
{
wordDocument.ExtendedFilePropertiesPart.Properties = new Properties(new Company(model.SiteName));
}
else
{
wordDocument.ExtendedFilePropertiesPart.Properties.Company = new Company(model.SiteName);
}
}
My problem is that I can't work out how the set the Publish Date property. I have tried adding it as a Custom File Property using the below code (which is adapted from https://www.snip2code.com/Snippet/292005/WDSetCustomProperty), but this does not work. I've read a few things about setting custom properties, but I'm confused how they're meant to work. I'm also unsure if the Publish Date should actually be set as a custom property, or some other type of property.
var customProps = wordDocument.CustomFilePropertiesPart;
if (customProps == null)
{
customProps = wordDocument.AddCustomFilePropertiesPart();
customProps.Properties = new DocumentFormat.OpenXml.CustomProperties.Properties();
}
var properties1 = new DocumentFormat.OpenXml.CustomProperties.Properties();
//I have tried both of these lines, neither worked.
//properties1.AddNamespaceDeclaration("op", "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties");
properties1.AddNamespaceDeclaration("vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
var customDocumentProperty1 = new DocumentFormat.OpenXml.CustomProperties.CustomDocumentProperty()
{
FormatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}",
PropertyId = 2,
Name = "Publish Date"
};
customDocumentProperty1.Append(new DocumentFormat.OpenXml.VariantTypes.VTLPWSTR { Text = DateTime.Today.ToShortDateString() });
properties1.Append(customDocumentProperty1);
part.Properties = properties1;
What type of property should the Publish Date be set as, and what is the right syntax for setting this?
Update: I have found that Publish Date is a CoverPageProperty which can be created using the below snippet, but I still haven't found how to set it correctly within the document.
var coverPageProps = new DocumentFormat.OpenXml.Office.CoverPageProps.CoverPageProperties
{
PublishDate = new PublishDate(DateTime.Today.ToShortDateString())
};
Adding the below code to my SetDocumentProperties method seems to work. I must admit I don't fully understand the below code, so any explanation would still be welcome. Additionally, if anyone has a solution which doesn't include writing XML as a string inside C# I would much prefer to avoid that.
const string publishDatePartId = "publishDatePart";
var publishDateXmlPart = wordDocument.MainDocumentPart.AddNewPart<CustomXmlPart>("application/xml", publishDatePartId);
var writer = new XmlTextWriter(publishDateXmlPart.GetStream(FileMode.Create), System.Text.Encoding.UTF8);
writer.WriteRaw($"<CoverPageProperties xmlns=\"http://schemas.microsoft.com/office/2006/coverPageProps\">" +
$"<PublishDate>{DateTime.Today.ToShortDateString()}</PublishDate>" +
$"</CoverPageProperties>");
writer.Flush();
writer.Close();
var customXmlPropertiesPart = publishDateXmlPart.AddNewPart<CustomXmlPropertiesPart>(publishDatePartId);
customXmlPropertiesPart.DataStoreItem = new DocumentFormat.OpenXml.CustomXmlDataProperties.DataStoreItem()
{
//I don't know what this ID is, but it seems to somehow relate to the Publish Date
ItemId = "{55AF091B-3C7A-41E3-B477-F2FDAA23CFDA}"
};

changing the sourcetable of a linked table in access 2007 with C#

I'll start by asking am I right in thinking that in the image below:
the 'TABLE=CLOASEUCDBA.T_BASIC_POLICY' is not part of the connection string? in fact it is the source table name?
I'm looking to alter this to another linked table on the same database. The connection string should there be the same and the name that appears in ACCESS should be the same. The only difference should be under the hood it is actually referencing another table and of course if you open the table it will contain different fields and data.
my code for far to do this is:
var dbe = new DBEngine();
Database db = dbe.OpenDatabase(#"C:\Users\xxxx\Documents\Test.accdb");
foreach (TableDef tbd in db.TableDefs)
{
if (tbd.Name.Contains("CLOASEUCDBA_T_BASIC_POLICY"))
{
tbd.SourceTableName = "CLOASEUCDBA_T_BILLING_INFORMATION";
}
}
db.Close();
However I'm getting a big fat COMException "Cannot set this property once the object is part of a collection.". I'm not sure exactly why and all the examples I can find online are all written in VB/VBA and I only have very very limited exposure to this. Any help is appreciated.
EDIT:
I have tried to go a different route with no futher success using the code:
if (tbd.Name.Contains("CLOASEUCDBA_T_BASIC_POLICY"))
{
var newtable = db.CreateTableDef("this is a new table");
newtable.Name = "new table";
newtable.Connect = tbd.Connect;
newtable.SourceTableName = "CLOASEUCDBA_T_BILLING_INFORMATION";
db.TableDefs.Append(newtable);
//tbd.SourceTableName = "CLOASEUCDBA_T_BILLING_INFORMATION";
}
In this case I get the error "ODBC--call failed."
Since we're not allowed to change the SourceTableName of a TableDef object that already exists in the TableDefs collection we need to create a new TableDef object, .Delete the old one, and then .Append the new one:
// This code requires the following COM reference in your project:
//
// Microsoft Office 14.0 Access Database Engine Object Library
//
// and the declaration
//
// using Microsoft.Office.Interop.Access.Dao;
//
// at the top of the class file
string tableDefName = "CLOASEUCDBA_T_BASIC_POLICY";
var dbe = new DBEngine();
Database db = dbe.OpenDatabase(#"C:\Users\xxxx\Documents\Test.accdb");
var tbdOld = db.TableDefs[tableDefName];
var tbdNew = db.CreateTableDef(tableDefName);
tbdNew.Connect = tbdOld.Connect;
tbdNew.SourceTableName = "CLOASEUCDBA_T_BILLING_INFORMATION";
db.TableDefs.Delete(tableDefName); // remove the old TableDef ...
db.TableDefs.Append(tbdNew); // ... and append the new one
db.Close();

c# : Dynamically adding new User Settings to Settings.Default.Properties collection, and saving them once form is closed.

I'm a novice programmer using Visual C# 2010. I am trying to dynamically (during run time) create a new SettingsProperty and add it to the Settings.Default.Properties collection in my application (new settings). These properties are essentially user defined views (stored in a string) that I want to save for later reloading. I have tried using the code below but it doesn't seem to be working. When I close the application, the newly created and saved properties are gone.
private void button6_Click(object sender, EventArgs e)
{
string connectionText = maskedTextBox3.Text;
string vusipsText = maskedTextBox2.Text;
string chartText = maskedTextBox1.Text;
string[] settingsArray = { connectionText, chartText, vusipsText };
string saveSettings = String.Join(":", settingsArray);
//configure new property
SettingsProperty property = new SettingsProperty("kri");
property.DefaultValue = saveSettings;
property.IsReadOnly = false;
property.PropertyType = typeof(string);
property.Provider = Settings.Default.Providers["LocalFileSettingsProvider"];
property.Attributes.Add(typeof(System.Configuration.UserScopedSettingAttribute), new System.Configuration.UserScopedSettingAttribute());
Settings.Default.Properties.Add(property);
//Properties.Settings.Default.Reload();
Settings.Default.Save();
ActiveForm.Close();
}
How can I get around this issue?
Thanks
Your code looks fine, but the Settings doesn't know about your property next time you load the data. If you define your property again (at load time) the value should be available. This is a working sample out of a loop that I use to save enums:
If My.Settings.Properties(settingName) Is Nothing Then
Dim p = New Configuration.SettingsProperty(settingName)
p.Provider = My.Settings.Providers("LocalFileSettingsProvider")
p.Attributes.Add(GetType(Configuration.UserScopedSettingAttribute), _
New Configuration.UserScopedSettingAttribute())
p.PropertyType = GetType(SampleEnum)
My.Settings.Properties.Add(p)
If My.Settings(settingName) Is Nothing Then
My.Settings(settingName) = SampleEnum.DefaultValue
End If
End If
Always run the code at startup to create the property and for the first time to create the value, too.

Web.config issue - The given key was not present in the dictionary

I have ran into a really annoying issue which gives me this error: "The given key was not present in the dictionary."
What I don't get is that it worked perfectly as intedded last friday and the days before that. I have debugged, checked if the webservice files were intact etc. It all fits.
All I did last friday was running a script which ran trough all of the items in my list which contains the article pages and edited their creation date. I don't know if that could have changed something, but that's the only thing I can recall.
ASPX.CS
protected void Page_Load(object sender, EventArgs e)
{
var listId = Request.QueryString["ListID"];
var itemId = Request.QueryString["ItemID"];
try
{
var spList = SPContext.Current.Web.Lists[new Guid(listId)];
var item = spList.GetItemById(int.Parse(itemId));
var image = (ImageFieldValue)item["PublishingPageImage"];
var contentType = (string)item["ContentType"];
var pageLayout = (string) item["PublishingPageLayout"];
var news = new News
{
Title = (string)item["Title"],
NewsId = item.UniqueId,
Content = (string)item["PublishingPageContent"],
ArticleDate = item["ArticleStartDate"] == null ? DateTime.Now : (DateTime)item["ArticleStartDate"],
PageName = item.File.Name,
Author = new SPFieldUserValue(SPContext.Current.Web, (string)item["Author"]).User.LoginName,
IsArticle = contentType.Contains("Article"),
PageLayout = GetLayout(pageLayout),
Image = GetImage(image)
};
// Jumps to the WSInstance class.
WSInstance.InternetInstance().PublishNews(news); // This line throws the exception.
lblMessage.Text = "News '<i>" + news.Title + "</i>' have been published succesfully to the Internet site.";
}
catch (Exception ex)
{
EventLogger.LogError("Error occured while publishing news: " + ex.Message + "\n" + ex.StackTrace, this);
}
}
WSINSTANCE
public static WSIntegration InternetInstance(SPSite spSite)
{
// Jumps to the Configuration class.
var url = Configuration.GetConfigurationValue("Progressive.WS.Internet", spSite);
...
return new WSIntegration
{
Credentials = new NetworkCredential(username, password, domain),
Url = url
};
}
public static WSIntegration InternetInstance()
{
return InternetInstance(SPContext.Current.Site);
}
CONFIGURATION
public static class Configuration
{
public static string GetConfigurationValue(string key, SPSite site)
{
var name = site.WebApplication.IisSettings[site.Zone].ServerComment; // This is where it fails and throws the error: "The given key was not present in the dictionary."
var value = "";
SPSecurity.RunWithElevatedPrivileges(() => { value = WebConfigurationManager.OpenWebConfiguration("/", name).AppSettings.Settings[key].Value; });
return value;
}
}
The section which it gets hold of the data from the web.config file.
<appSettings><add key="Progressive.WS.Internet" value="http://shpt02/_layouts/DR/WSIntegration.asmx" /> // This is the key value it cannot find.
<add key="Progressive.WS.Internet.Username" value="user" />
<add key="Progressive.WS.Internet.Password" value="password" />
<add key="Progressive.WS.Internet.Domain" value="domain" /></appSettings>
The error says that it can't find the site's Zone in the IisSettings dictionary. You should check both the value of the Zone property and the contents of the IisSettings dictionary. They may not contain the values you expect, since you access the IisSettings outside RunWithElevatedPrivileges, ie. with the end user's access rights.
In any case storing application settings in web.config is not the best option in SharePoint, as a web application hosts many site collections and sites. Modifying it causes all the sites to restart and recompile - not a good end user experience!
Check the Application Settings Manager section in the Sharepoint 2010 Guidance for an alternative way that stores settings in the appropriate site's property bag.
Saw Steve's comment and agree that any pointers to where the error is occuring would be good. Is this Silverlight (or WPF)? If so, it can be a styling name you used in your XAML is not present in the dictionary. Check names carefully and determine if there is an issue here.
Both are possible locations for the issue. Naming issues are often missed as you run through code.

Categories

Resources