├── AppConfiguration.png ├── Westwind.ApplicationConfiguration.WebSample ├── Views │ ├── _ViewStart.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ └── _Layout.cshtml │ ├── Web.config │ └── Samples │ │ └── Index.cshtml ├── Global.asax ├── img │ ├── github.png │ ├── nuget.png │ ├── NugetIcon.png │ ├── wwToolbarLogo.png │ ├── WebSiteConfigLogo.jpg │ ├── glyphicons-halflings.png │ ├── glyphicons-halflings-white.png │ ├── ApplicationConfigurationLogo.png │ ├── ApplicationConfigurationLogo_65.png │ └── ApplicationConfigurationLogo_128x128.png ├── Css │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── bootstrap-responsive.min.css ├── Controllers │ ├── Code │ │ ├── SampleHelpers │ │ │ ├── WebUtils.cs │ │ │ ├── StringUtils.cs │ │ │ ├── ReflectionUtils.cs │ │ │ └── MyModel.cs │ │ ├── App.cs │ │ └── ApplicationConfiguration.cs │ └── SamplesViewModel.cs ├── packages.config ├── WebStore.config ├── Global.asax.cs ├── Web.Debug.config ├── Web.Release.config ├── Properties │ └── AssemblyInfo.cs ├── js │ ├── bootstrap-alert.js │ └── bootstrap-dropdown.js ├── Web.config ├── Index.htm └── Westwind.ApplicationConfiguration.WebSample.csproj ├── lib └── Westwind.Utilities.Configuration.dll ├── west wind application configuration for .net.chm ├── Westwind.Utilities.Configuration.Tests ├── Database.sdf ├── packages.config ├── SupportClasses │ ├── DebugModes.cs │ └── TestHelpers.cs ├── Models │ ├── Entities │ │ ├── LineItem.cs │ │ ├── Order.cs │ │ ├── Customer.cs │ │ └── WebStoreContext.cs │ └── DataBaseInitializer.cs ├── ConfigurationClasses │ ├── LicenseInformation.cs │ ├── StringConfigFileConfiguration.cs │ ├── JsonFileConfiguration.cs │ ├── XmlFileConfiguration.cs │ ├── CustomConfigFileConfiguration.cs │ ├── AutoConfigFileConfiguration.cs │ └── DatabaseConfiguration.cs ├── Westwind.Utilities.Configuration.Tests.dll.config ├── MiscellaneousConfigurationTests.cs ├── MyCustomConfigurationSection.cs ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── DatabaseConfigurationTests.cs ├── JsonFileConfigurationTests.cs ├── XmlFileConfigurationTests.cs ├── StringConfigurationTests.cs ├── CustomConfigFileConfigurationTests.cs ├── AutoConfigFileConfigurationTests.cs └── Westwind.Utilities.Configuration.Tests.csproj ├── Westwind.Utilities.Configuration ├── AppConfiguration.cs ├── Support │ ├── Data │ │ ├── DataUtils.cs │ │ └── SqlDataAccess.cs │ └── Utilities │ │ ├── Encryption.cs │ │ ├── StringUtils.cs │ │ ├── ReflectionUtils.cs │ │ ├── SerializationUtils.cs │ │ ├── JsonSerializationUtils.cs │ │ └── StringSerializer.cs ├── Providers │ ├── IConfigurationProvider.cs │ ├── ConfigurationProviderBase.cs │ ├── StringConfigurationProvider.cs │ ├── XmlFileConfigurationProvider.cs │ ├── JsonFileConfigurationProvider.cs │ ├── SqlServerConfigurationProvider.cs │ └── ConfigurationFileConfigurationProvider.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Westwind.Utilities.Configuration.csproj └── AppConfiguration.cd ├── .nuget ├── NuGet.Config └── NuGet.targets ├── .gitignore ├── Westwind.ApplicationConfiguration.sln └── Changelog.md /AppConfiguration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/AppConfiguration.png -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } -------------------------------------------------------------------------------- /lib/Westwind.Utilities.Configuration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/lib/Westwind.Utilities.Configuration.dll -------------------------------------------------------------------------------- /west wind application configuration for .net.chm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/west wind application configuration for .net.chm -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="ApplicationConfigurationSamples.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/Database.sdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration.Tests/Database.sdf -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/AppConfiguration.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/AppConfiguration.cs -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/github.png -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/nuget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/nuget.png -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Support/Data/DataUtils.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Support/Data/DataUtils.cs -------------------------------------------------------------------------------- /.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/NugetIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/NugetIcon.png -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Support/Data/SqlDataAccess.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Support/Data/SqlDataAccess.cs -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Support/Utilities/Encryption.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Support/Utilities/Encryption.cs -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/wwToolbarLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/wwToolbarLogo.png -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Support/Utilities/StringUtils.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Support/Utilities/StringUtils.cs -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/WebSiteConfigLogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/WebSiteConfigLogo.jpg -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Providers/IConfigurationProvider.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Providers/IConfigurationProvider.cs -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Support/Utilities/ReflectionUtils.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Support/Utilities/ReflectionUtils.cs -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Css/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/Css/fontawesome-webfont.eot -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Css/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/Css/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Providers/ConfigurationProviderBase.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Providers/ConfigurationProviderBase.cs -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Css/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/Css/fontawesome-webfont.woff -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Providers/StringConfigurationProvider.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Providers/StringConfigurationProvider.cs -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Providers/XmlFileConfigurationProvider.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Providers/XmlFileConfigurationProvider.cs -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Support/Utilities/SerializationUtils.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Support/Utilities/SerializationUtils.cs -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Providers/JsonFileConfigurationProvider.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Providers/JsonFileConfigurationProvider.cs -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Providers/SqlServerConfigurationProvider.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Providers/SqlServerConfigurationProvider.cs -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Support/Utilities/JsonSerializationUtils.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Support/Utilities/JsonSerializationUtils.cs -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/ApplicationConfigurationLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/ApplicationConfigurationLogo.png -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/ApplicationConfigurationLogo_65.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/ApplicationConfigurationLogo_65.png -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Providers/ConfigurationFileConfigurationProvider.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.Utilities.Configuration/Providers/ConfigurationFileConfigurationProvider.cs -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Controllers/Code/SampleHelpers/WebUtils.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/Controllers/Code/SampleHelpers/WebUtils.cs -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Controllers/Code/SampleHelpers/StringUtils.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/Controllers/Code/SampleHelpers/StringUtils.cs -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/img/ApplicationConfigurationLogo_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/img/ApplicationConfigurationLogo_128x128.png -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Controllers/Code/SampleHelpers/ReflectionUtils.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RickStrahl/Westwind.ApplicationConfiguration/HEAD/Westwind.ApplicationConfiguration.WebSample/Controllers/Code/SampleHelpers/ReflectionUtils.cs -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = null; 3 | } 4 | 5 | 6 | 7 | 8 | Error 9 | 10 | 11 |

12 | Sorry, an error occurred while processing your request. 13 |

14 | 15 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/SupportClasses/DebugModes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Westwind.Utilities.Configuration 8 | { 9 | public enum DebugModes 10 | { 11 | Default, 12 | ApplicationErrorMessage, 13 | DeveloperErrorMessage 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | @ViewBag.Title 6 | 7 | 8 | 9 | 10 | 11 | 12 | @RenderBody() 13 | 14 | 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | *.obj 3 | *.exe 4 | *.pdb 5 | *.user 6 | *.aps 7 | *.pch 8 | *.vspscc 9 | *_i.c 10 | *_p.c 11 | *.ncb 12 | *.suo 13 | *.sln.docstates 14 | *.tlb 15 | *.tlh 16 | *.bak 17 | *.cache 18 | *.ilk 19 | *.log 20 | [Bb]in 21 | [Dd]ebug*/ 22 | *.lib 23 | *.sbr 24 | obj/ 25 | [Rr]elease*/ 26 | _ReSharper*/ 27 | [Tt]est[Rr]esult* 28 | *.vssscc 29 | $tf*/ 30 | /packages 31 | /Westwind.ApplicationConfiguration.WebSample/Properties/PublishProfiles/*.pubxml 32 | /Westwind.ApplicationConfiguration.WebSample/Properties/PublishProfiles/*.pubxml 33 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Controllers/Code/SampleHelpers/MyModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | 6 | namespace ApplicationConfigurationWeb 7 | { 8 | /// 9 | /// Summary description for MyModel 10 | /// 11 | public class MyModel 12 | { 13 | public MyModel() 14 | { 15 | Name = "Rick"; 16 | Age = 20; 17 | Entered = DateTime.Now.Date; 18 | 19 | } 20 | 21 | public string Name { get; set; } 22 | public int Age { get; set; } 23 | public DateTime Entered { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/Models/Entities/LineItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Westwind.Data.Test.Models 8 | { 9 | public class LineItem 10 | { 11 | public int Id { get; set; } 12 | public int OrderId { get; set; } 13 | 14 | [MaxLength(30)] 15 | public string Sku { get; set; } 16 | [MaxLength(200)] 17 | public string Description { get; set; } 18 | public decimal Quantity { get; set; } 19 | public decimal Price { get; set; } 20 | 21 | public decimal Total { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Controllers/Code/App.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using Westwind.Utilities.Configuration; 6 | 7 | namespace ApplicationConfigurationWeb 8 | { 9 | /// 10 | /// Summary description for Class1 11 | /// 12 | public class App 13 | { 14 | public static ApplicationConfiguration Configuration { get; set; } 15 | 16 | static App() 17 | { 18 | // Create an instance of the class with default provider 19 | Configuration = new ApplicationConfiguration(); 20 | Configuration.Initialize(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/SupportClasses/TestHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.IO; 4 | 5 | namespace Westwind.Utilities.Configuration.Tests 6 | { 7 | public class TestHelpers 8 | { 9 | public static string GetTestConfigFilePath() 10 | { 11 | return (typeof(TestHelpers).Assembly.CodeBase + ".config") 12 | .Replace("file:///", ""); 13 | } 14 | 15 | public static void xDeleteTestConfigFile() 16 | { 17 | string configFile = GetTestConfigFilePath(); 18 | File.Delete(configFile); 19 | } 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/ConfigurationClasses/LicenseInformation.cs: -------------------------------------------------------------------------------- 1 | namespace Westwind.Utilities.Configuration.Tests 2 | { 3 | /// 4 | /// Demonstration class for a complex type 5 | /// 6 | public class LicenseInformation 7 | { 8 | public string Name { get; set; } 9 | public string Company { get; set; } 10 | public string LicenseKey { get; set; } 11 | 12 | public static LicenseInformation FromString(string data) 13 | { 14 | return StringSerializer.Deserialize(data,","); 15 | } 16 | 17 | public override string ToString() 18 | { 19 | return StringSerializer.SerializeObject(this, ","); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/Models/DataBaseInitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Westwind.Data.Test.Models; 8 | 9 | namespace Westwind.Data.Test 10 | { 11 | public class DatabaseInitializer 12 | { 13 | public static void InitializeDatabase() 14 | { 15 | // create database if it doesn't exist 16 | Database.SetInitializer(new WebStoreContextInitializer()); 17 | 18 | // force connection to be fired once 19 | var customer = new WebStoreContext().Customers.FirstOrDefault(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/Westwind.Utilities.Configuration.Tests.dll.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
6 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/Models/Entities/Order.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace Westwind.Data.Test.Models 9 | { 10 | public class Order 11 | { 12 | public int Id { get; set; } 13 | 14 | [ForeignKey("Customer")] 15 | public int CustomerPk { get; set; } 16 | 17 | public string OrderId { get; set; } 18 | public DateTime Entered { get; set; } 19 | public DateTime? Shipped { get; set; } 20 | 21 | public List LineItems { get; set; } 22 | public Customer Customer { get; set; } 23 | 24 | public Order() 25 | { 26 | Entered = DateTime.Now; 27 | Shipped = null; 28 | LineItems = new List(); 29 | } 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/MiscellaneousConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.Configuration; 4 | using System.Collections.Specialized; 5 | using System.IO; 6 | 7 | namespace Westwind.Utilities.Configuration.Tests 8 | { 9 | [TestClass] 10 | public class MiscellaneousConfigurationTests 11 | { 12 | 13 | 14 | [TestMethod] 15 | public void WriteAppSettingsTest() 16 | { 17 | var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 18 | var section = config.GetSection("appSettings") as AppSettingsSection; 19 | section.Settings.Add("NewKey", "Value"); 20 | config.Save(); 21 | 22 | // Config File and custom section should exist 23 | string text = File.ReadAllText(TestHelpers.GetTestConfigFilePath()); 24 | Assert.IsTrue(text.Contains("key=\"NewKey\"")); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/MyCustomConfigurationSection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Westwind.Utilities.Configuration 8 | { 9 | class MyCustomConfigurationSection : ConfigurationSection 10 | { 11 | [ConfigurationProperty("ApplicationName")] 12 | public string ApplicationName 13 | { 14 | get { return (string) this["ApplicationName"]; } 15 | set { this["ApplicationName"] = value; 16 | 17 | 18 | } 19 | } 20 | 21 | [ConfigurationProperty("MaxDisplayItems",DefaultValue=15)] 22 | public int MaxDisplayItems 23 | { 24 | get { return (int) this["MaxDisplayItems"]; } 25 | set { this["MaxDisplayItems"] = value; } 26 | } 27 | 28 | [ConfigurationProperty("DebugMode")] 29 | public DebugModes DebugMode 30 | { 31 | get { return (DebugModes) this["DebugMode"]; } 32 | set { this["DebugMode"] = value; } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/Models/Entities/Customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Westwind.Data.Test.Models 8 | { 9 | public class Customer 10 | { 11 | public int Id { get; set; } 12 | 13 | [MaxLength(50)] 14 | public string FirstName { get; set; } 15 | 16 | [MaxLength(50)] 17 | public string LastName { get; set; } 18 | 19 | [MaxLength(50)] 20 | public string Company { get; set; } 21 | 22 | [MaxLength(768)] 23 | public string Address { get; set; } 24 | 25 | [MaxLength(30)] 26 | public string Password { get; set; } 27 | 28 | public DateTime? LastOrder { get; set; } 29 | 30 | public DateTime Entered { get; set; } 31 | public DateTime Updated { get; set; } 32 | 33 | public List Orders { get; set; } 34 | 35 | public Customer() 36 | { 37 | Entered = DateTime.Now; 38 | Updated = DateTime.Now; 39 | Orders = new List(); 40 | } 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/WebStore.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Linq; 5 | using System.Web; 6 | using System.Web.Mvc; 7 | using System.Web.Routing; 8 | 9 | namespace ApplicationConfigurationSamples 10 | { 11 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 12 | // visit http://go.microsoft.com/?LinkId=9394801 13 | 14 | public class MvcApplication : System.Web.HttpApplication 15 | { 16 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 17 | { 18 | filters.Add(new HandleErrorAttribute()); 19 | } 20 | 21 | public static void RegisterRoutes(RouteCollection routes) 22 | { 23 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 24 | 25 | routes.MapRoute( 26 | "Default", // Route name 27 | "{controller}/{action}/{id}", // URL with parameters 28 | new { action = "Index", id = UrlParameter.Optional } // Parameter defaults 29 | ); 30 | 31 | } 32 | 33 | protected void Application_Start() 34 | { 35 | AreaRegistration.RegisterAllAreas(); 36 | RegisterGlobalFilters(GlobalFilters.Filters); 37 | RegisterRoutes(RouteTable.Routes); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ApplicationConfigurationSample")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ApplicationConfigurationSample")] 13 | [assembly: AssemblyCopyright("Copyright © 2003-2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("50243e09-1346-4e79-adea-02b48b9748a8")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Westwind.Utilities.Configuration.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Westwind.Utilities.Configuration.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("7cdc4e64-c4f0-4ce4-ae23-49534dfb2d65")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.99.0.0")] 36 | [assembly: AssemblyFileVersion("1.99.0.0")] 37 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Westwind.Utilities.Configuration")] 9 | [assembly: AssemblyDescription("Code-first, class based configurations for .NET")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("West Wind Technologies")] 12 | [assembly: AssemblyProduct("Westwind Utilities")] 13 | [assembly: AssemblyCopyright("Copyright © 2012-2014, West Wind Technologies")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1ce2e290-598a-410f-8eb3-9f0462ee3f69")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.25.0.0")] 36 | [assembly: AssemblyFileVersion("2.25.0.0")] 37 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/ConfigurationClasses/StringConfigFileConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Westwind.Utilities.Configuration.Tests 8 | { 9 | /// 10 | /// Custom Configuration Provider implementation that allows 11 | /// uses a different section and encrypts a couple of properties 12 | /// 13 | public class StringConfiguration : Westwind.Utilities.Configuration.AppConfiguration 14 | { 15 | public string ApplicationName { get; set; } 16 | public DebugModes DebugMode { get; set; } 17 | public int MaxDisplayListItems { get; set; } 18 | public bool SendAdminEmailConfirmations { get; set; } 19 | public string Password { get; set; } 20 | public string AppConnectionString { get; set; } 21 | 22 | // Must implement public default constructor 23 | public StringConfiguration() 24 | { 25 | ApplicationName = "Configuration Tests"; 26 | DebugMode = DebugModes.Default; 27 | MaxDisplayListItems = 15; 28 | SendAdminEmailConfirmations = false; 29 | Password = "seekrit"; 30 | AppConnectionString = "server=.;database=hosers;uid=bozo;pwd=seekrit;"; 31 | } 32 | 33 | protected override IConfigurationProvider OnCreateDefaultProvider(string sectionName, object configData) 34 | { 35 | var provider = new StringConfigurationProvider() 36 | { 37 | InitialStringData = configData as String, 38 | EncryptionKey = "ultra-seekrit", // use a generated value here 39 | PropertiesToEncrypt = "Password,AppConnectionString", 40 | }; 41 | 42 | return provider; 43 | } 44 | 45 | /// 46 | /// Optional - easier overload for xml string loading 47 | /// 48 | /// 49 | public void Initialize(string xml) 50 | { 51 | base.Initialize(configData: xml); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/ConfigurationClasses/JsonFileConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Web; 7 | 8 | namespace Westwind.Utilities.Configuration.Tests 9 | { 10 | /// 11 | /// Custom Configuration Provider implementation that allows 12 | /// uses a different section and encrypts a couple of properties 13 | /// 14 | public class JsonFileConfiguration : Westwind.Utilities.Configuration.AppConfiguration 15 | { 16 | public string ApplicationName { get; set; } 17 | public DebugModes DebugMode { get; set; } 18 | public int MaxDisplayListItems { get; set; } 19 | public bool SendAdminEmailConfirmations { get; set; } 20 | public string Password { get; set; } 21 | public string AppConnectionString { get; set; } 22 | public LicenseInformation License { get; set; } 23 | 24 | // Must implement public default constructor 25 | public JsonFileConfiguration() 26 | { 27 | ApplicationName = "Configuration Tests"; 28 | DebugMode = DebugModes.Default; 29 | MaxDisplayListItems = 15; 30 | SendAdminEmailConfirmations = false; 31 | Password = "seekrit"; 32 | AppConnectionString = "server=.;database=hosers;uid=bozo;pwd=seekrit;"; 33 | License = new LicenseInformation 34 | { 35 | Name = "Rick", 36 | Company = "West Wind", 37 | LicenseKey = "RickWestWind-533112" 38 | }; 39 | } 40 | 41 | 42 | // Automatically initialize with default config and config file 43 | public void Initialize(string configFile) 44 | { 45 | base.Initialize(configData: configFile); 46 | } 47 | 48 | protected override IConfigurationProvider OnCreateDefaultProvider(string sectionName, object configData) 49 | { 50 | string jsonFile = "JsonConfiguration.txt"; 51 | if (configData != null) 52 | jsonFile = configData as string; 53 | 54 | var provider = new JsonFileConfigurationProvider() 55 | { 56 | JsonConfigurationFile = jsonFile, 57 | EncryptionKey = "ultra-seekrit", // use a generated value here 58 | PropertiesToEncrypt = "Password,AppConnectionString,License.LicenseKey" 59 | }; 60 | 61 | return provider; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/ConfigurationClasses/XmlFileConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Web; 7 | 8 | namespace Westwind.Utilities.Configuration.Tests 9 | { 10 | /// 11 | /// Custom Configuration Provider implementation that allows 12 | /// uses a different section and encrypts a couple of properties 13 | /// 14 | public class XmlFileConfiguration : Westwind.Utilities.Configuration.AppConfiguration 15 | { 16 | public string ApplicationName { get; set; } 17 | public DebugModes DebugMode { get; set; } 18 | public int MaxDisplayListItems { get; set; } 19 | public bool SendAdminEmailConfirmations { get; set; } 20 | public string Password { get; set; } 21 | public string AppConnectionString { get; set; } 22 | public LicenseInformation License {get; set; } 23 | 24 | 25 | // Must implement public default constructor 26 | public XmlFileConfiguration() 27 | { 28 | ApplicationName = "Configuration Tests"; 29 | DebugMode = DebugModes.Default; 30 | MaxDisplayListItems = 15; 31 | SendAdminEmailConfirmations = false; 32 | Password = "seekrit"; 33 | License = new LicenseInformation() 34 | { 35 | Company = "West Wind", 36 | Name = "Rick", 37 | LicenseKey = "westwindrick-4123122" 38 | }; 39 | AppConnectionString = "server=.;database=hosers;uid=bozo;pwd=seekrit;"; 40 | } 41 | 42 | 43 | // Automatically initialize with default config and config file 44 | public void Initialize(string configFile) 45 | { 46 | base.Initialize(configData: configFile); 47 | } 48 | 49 | protected override IConfigurationProvider OnCreateDefaultProvider(string sectionName, object configData) 50 | { 51 | string xmlFile = "XmlConfiguration.xml"; 52 | if (configData != null) 53 | xmlFile = xmlFile; 54 | 55 | var provider = new XmlFileConfigurationProvider() 56 | { 57 | XmlConfigurationFile = xmlFile, 58 | EncryptionKey = "ultra-seekrit", // use a generated value here 59 | PropertiesToEncrypt = "Password,AppConnectionString,License.LicenseKey" 60 | // UseBinarySerialization = true 61 | }; 62 | 63 | return provider; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/ConfigurationClasses/CustomConfigFileConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Westwind.Utilities.Configuration.Tests 8 | { 9 | /// 10 | /// Custom Configuration Provider implementation that allows 11 | /// uses a different section and encrypts a couple of properties 12 | /// 13 | public class CustomConfigFileConfiguration : Westwind.Utilities.Configuration.AppConfiguration 14 | { 15 | public string ApplicationName { get; set; } 16 | public DebugModes DebugMode { get; set; } 17 | public int MaxDisplayListItems { get; set; } 18 | public bool SendAdminEmailConfirmations { get; set; } 19 | public string Password { get; set; } 20 | public string AppConnectionString { get; set; } 21 | public LicenseInformation License { get; set; } 22 | public List ServerList { get; set; } 23 | 24 | public CustomConfigFileConfiguration() 25 | { 26 | ApplicationName = "Configuration Tests"; 27 | DebugMode = DebugModes.Default; 28 | MaxDisplayListItems = 15; 29 | SendAdminEmailConfirmations = false; 30 | Password = "seekrit"; 31 | AppConnectionString = "server=.;database=hosers;uid=bozo;pwd=seekrit;"; 32 | License = new LicenseInformation() 33 | { 34 | Company = "West Wind", 35 | Name = "Rick", 36 | LicenseKey = "westwindrick-51123" 37 | }; 38 | ServerList = new List() 39 | { 40 | "DevServer", 41 | "Maximus", 42 | "Tempest" 43 | }; 44 | } 45 | 46 | /// 47 | /// Override to provide a custom default provider (created when Initialize() is 48 | /// called with no parameters). 49 | /// 50 | /// 51 | /// 52 | /// 53 | protected override IConfigurationProvider OnCreateDefaultProvider(string sectionName, object configData) 54 | { 55 | var provider = new ConfigurationFileConfigurationProvider() 56 | { 57 | //ConfigurationFile = "CustomConfiguration.config", 58 | ConfigurationSection = sectionName, 59 | EncryptionKey = "ultra-seekrit", // use a generated value here 60 | PropertiesToEncrypt = "Password,AppConnectionString,License.LicenseKey" 61 | }; 62 | 63 | return provider; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/js/bootstrap-alert.js: -------------------------------------------------------------------------------- 1 | /* ========================================================== 2 | * bootstrap-alert.js v2.0.4 3 | * http://twitter.github.com/bootstrap/javascript.html#alerts 4 | * ========================================================== 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ========================================================== */ 19 | 20 | 21 | !function ($) { 22 | 23 | "use strict"; // jshint ;_; 24 | 25 | 26 | /* ALERT CLASS DEFINITION 27 | * ====================== */ 28 | 29 | var dismiss = '[data-dismiss="alert"]' 30 | , Alert = function (el) { 31 | $(el).on('click', dismiss, this.close) 32 | } 33 | 34 | Alert.prototype.close = function (e) { 35 | var $this = $(this) 36 | , selector = $this.attr('data-target') 37 | , $parent 38 | 39 | if (!selector) { 40 | selector = $this.attr('href') 41 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 42 | } 43 | 44 | $parent = $(selector) 45 | 46 | e && e.preventDefault() 47 | 48 | $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) 49 | 50 | $parent.trigger(e = $.Event('close')) 51 | 52 | if (e.isDefaultPrevented()) return 53 | 54 | $parent.removeClass('in') 55 | 56 | function removeElement() { 57 | $parent 58 | .trigger('closed') 59 | .remove() 60 | } 61 | 62 | $.support.transition && $parent.hasClass('fade') ? 63 | $parent.on($.support.transition.end, removeElement) : 64 | removeElement() 65 | } 66 | 67 | 68 | /* ALERT PLUGIN DEFINITION 69 | * ======================= */ 70 | 71 | $.fn.alert = function (option) { 72 | return this.each(function () { 73 | var $this = $(this) 74 | , data = $this.data('alert') 75 | if (!data) $this.data('alert', (data = new Alert(this))) 76 | if (typeof option == 'string') data[option].call($this) 77 | }) 78 | } 79 | 80 | $.fn.alert.Constructor = Alert 81 | 82 | 83 | /* ALERT DATA-API 84 | * ============== */ 85 | 86 | $(function () { 87 | $('body').on('click.alert.data-api', dismiss, Alert.prototype.close) 88 | }) 89 | 90 | }(window.jQuery); -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Views/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/ConfigurationClasses/AutoConfigFileConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Westwind.Utilities.Configuration.Tests 8 | { 9 | /// 10 | /// Default implementation that uses only base constructors 11 | /// for configuration. 12 | /// 13 | /// Default setup allows for no configuration of the provider 14 | /// since we're just calling back to the base constructors 15 | /// 16 | /// Note: for config files ONLY you can implement the default 17 | /// constructor automatically since no serialization is used. 18 | /// When using XML, String, Database the default constructor 19 | /// needs to be left at default to avoid recursive loading 20 | /// 21 | class AutoConfigFileConfiguration : Westwind.Utilities.Configuration.AppConfiguration 22 | { 23 | public string ApplicationName { get; set; } 24 | public DebugModes DebugMode { get; set; } 25 | public int MaxDisplayListItems { get; set; } 26 | public bool SendAdminEmailConfirmations { get; set; } 27 | public string MailServer { get; set; } 28 | public string MailServerPassword { get; set; } 29 | 30 | /// 31 | /// Type that has ToString() and FromString() methods 32 | /// to allow serialization 33 | /// 34 | public LicenseInformation License { get; set; } 35 | 36 | public AutoConfigFileConfiguration() 37 | { 38 | ApplicationName = "Configuration Tests"; 39 | DebugMode = DebugModes.Default; 40 | MaxDisplayListItems = 15; 41 | SendAdminEmailConfirmations = false; 42 | MailServer = "mail.MyWickedServer.com:334"; 43 | MailServerPassword = "seekrity"; 44 | License = new LicenseInformation() 45 | { 46 | Name = "Rick", 47 | Company = "West Wind", 48 | LicenseKey = "WestWind-5333121" 49 | }; 50 | } 51 | 52 | 53 | } 54 | 55 | /// 56 | /// This version of the class internally calls Initialize 57 | /// to read configuration information immediately from 58 | /// itself so no explicit call to Initialize is required 59 | /// 60 | class AutoConfigFile2Configuration : AppConfiguration 61 | { 62 | public string ApplicationName { get; set; } 63 | public DebugModes DebugMode { get; set; } 64 | public int MaxDisplayListItems { get; set; } 65 | public bool SendAdminEmailConfirmations { get; set; } 66 | 67 | public AutoConfigFile2Configuration() 68 | { 69 | ApplicationName = "Configuration Tests"; 70 | DebugMode = DebugModes.Default; 71 | MaxDisplayListItems = 15; 72 | SendAdminEmailConfirmations = false; 73 | 74 | // Automatically initialize this one 75 | this.Initialize(); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30110.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Westwind.Utilities.Configuration", "Westwind.Utilities.Configuration\Westwind.Utilities.Configuration.csproj", "{1D865318-2863-4424-B650-58F220439D64}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Westwind.ApplicationConfiguration.WebSample", "Westwind.ApplicationConfiguration.WebSample\Westwind.ApplicationConfiguration.WebSample.csproj", "{2CEBB8E2-46F5-4716-A866-48B2A2E33206}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Westwind.Utilities.Configuration.Tests", "Westwind.Utilities.Configuration.Tests\Westwind.Utilities.Configuration.Tests.csproj", "{7462B3A1-4894-4F1A-8B16-7B8D058EAC13}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AE222598-5F06-4CD1-A067-E1FFBB2E3B51}" 13 | ProjectSection(SolutionItems) = preProject 14 | Changelog.md = Changelog.md 15 | Readme.md = Readme.md 16 | EndProjectSection 17 | EndProject 18 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3C08A58E-CA83-4EE6-93BB-345C536893F4}" 19 | EndProject 20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{36407585-4490-4FAB-9A85-F071C4B3279C}" 21 | ProjectSection(SolutionItems) = preProject 22 | .nuget\NuGet.Config = .nuget\NuGet.Config 23 | .nuget\NuGet.exe = .nuget\NuGet.exe 24 | .nuget\NuGet.targets = .nuget\NuGet.targets 25 | EndProjectSection 26 | EndProject 27 | Global 28 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 29 | Debug|Any CPU = Debug|Any CPU 30 | Release|Any CPU = Release|Any CPU 31 | EndGlobalSection 32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 33 | {1D865318-2863-4424-B650-58F220439D64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {1D865318-2863-4424-B650-58F220439D64}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {1D865318-2863-4424-B650-58F220439D64}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {1D865318-2863-4424-B650-58F220439D64}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {2CEBB8E2-46F5-4716-A866-48B2A2E33206}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {2CEBB8E2-46F5-4716-A866-48B2A2E33206}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {2CEBB8E2-46F5-4716-A866-48B2A2E33206}.Release|Any CPU.ActiveCfg = Release|Any CPU 40 | {2CEBB8E2-46F5-4716-A866-48B2A2E33206}.Release|Any CPU.Build.0 = Release|Any CPU 41 | {7462B3A1-4894-4F1A-8B16-7B8D058EAC13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {7462B3A1-4894-4F1A-8B16-7B8D058EAC13}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {7462B3A1-4894-4F1A-8B16-7B8D058EAC13}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {7462B3A1-4894-4F1A-8B16-7B8D058EAC13}.Release|Any CPU.Build.0 = Release|Any CPU 45 | EndGlobalSection 46 | GlobalSection(SolutionProperties) = preSolution 47 | HideSolutionNode = FALSE 48 | EndGlobalSection 49 | GlobalSection(NestedProjects) = preSolution 50 | {7462B3A1-4894-4F1A-8B16-7B8D058EAC13} = {3C08A58E-CA83-4EE6-93BB-345C536893F4} 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/ConfigurationClasses/DatabaseConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Westwind.Utilities.Configuration.Tests 8 | { 9 | /// 10 | /// Custom Configuration Provider implementation that allows 11 | /// uses a different section and encrypts a couple of properties 12 | /// 13 | public class DatabaseConfiguration : Westwind.Utilities.Configuration.AppConfiguration 14 | { 15 | // Configuration store values 16 | public string ApplicationName { get; set; } 17 | public DebugModes DebugMode { get; set; } 18 | public int MaxDisplayListItems { get; set; } 19 | public bool SendAdminEmailConfirmations { get; set; } 20 | public string Password { get; set; } 21 | public string AppConnectionString { get; set; } 22 | 23 | // Must implement public default constructor 24 | public DatabaseConfiguration() 25 | { 26 | ApplicationName = "Configuration Tests"; 27 | DebugMode = DebugModes.Default; 28 | MaxDisplayListItems = 15; 29 | SendAdminEmailConfirmations = false; 30 | Password = "seekrit"; 31 | AppConnectionString = "server=.;database=hosers;uid=bozo;pwd=seekrit;"; 32 | } 33 | 34 | 35 | ///// 36 | ///// Override this method to create the custom default provider - in this case a database 37 | ///// provider with a few options. 38 | ///// 39 | protected override IConfigurationProvider OnCreateDefaultProvider(string sectionName, object configData) 40 | { 41 | string connectionString = "WestwindToolkitSamples"; 42 | string tableName = "ConfigurationData"; 43 | 44 | // ConfigData: new { ConnectionString = "...", Tablename = "..." } 45 | if (configData != null) 46 | { 47 | dynamic data = configData; 48 | connectionString = data.ConnectionString; 49 | tableName = data.Tablename; 50 | } 51 | 52 | var provider = new SqlServerConfigurationProvider() 53 | { 54 | Key = 0, 55 | ConnectionString = connectionString, 56 | Tablename = tableName, 57 | //ProviderName = "System.Data.SqlServerCe.4.0", 58 | EncryptionKey = "ultra-seekrit", // use a generated value here 59 | PropertiesToEncrypt = "Password,AppConnectionString" 60 | }; 61 | 62 | return provider; 63 | } 64 | 65 | /// 66 | /// Optional - Create a custom overload with required parameters 67 | /// 68 | public void Initialize(string connectionString, string tableName = null) 69 | { 70 | // pass in anonymous object with parameters we're interested in 71 | // the OnCreateDefaultProvider reads the anonymous object values 72 | // and uses them for the SQL access object 73 | Initialize(configData: new { ConnectionString = connectionString, Tablename = tableName }); 74 | } 75 | 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/DatabaseConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.IO; 4 | using Westwind.Data.Test; 5 | 6 | namespace Westwind.Utilities.Configuration.Tests 7 | { 8 | /// 9 | /// Tests default config file implementation that uses 10 | /// only base constructor behavior - (config file and section config only) 11 | /// 12 | [TestClass] 13 | public class DatabaseConfigurationTests 14 | { 15 | 16 | 17 | 18 | private TestContext testContextInstance; 19 | 20 | /// 21 | ///Gets or sets the test context which provides 22 | ///information about and functionality for the current test run. 23 | /// 24 | public TestContext TestContext 25 | { 26 | get 27 | { 28 | return testContextInstance; 29 | } 30 | set 31 | { 32 | testContextInstance = value; 33 | } 34 | } 35 | 36 | [ClassInitialize()] 37 | public static void TestClassInitialize(TestContext testContext) 38 | { 39 | DatabaseInitializer.InitializeDatabase(); 40 | } 41 | 42 | 43 | /// 44 | /// Note: For Web Apps this should be a complete path. 45 | /// Here the filename references the current directory 46 | /// 47 | [TestMethod] 48 | public void DefaultConstructorInstanceTest() 49 | { 50 | // this should create the database table and add default 51 | // data into it if it doesn't exist - otherwise 52 | // the values are read 53 | var config = new DatabaseConfiguration(); 54 | config.Initialize(); 55 | 56 | Assert.IsNotNull(config); 57 | Assert.IsFalse(string.IsNullOrEmpty(config.ApplicationName)); 58 | } 59 | 60 | [TestMethod] 61 | public void WriteConfigurationTest() 62 | { 63 | var config = new DatabaseConfiguration(); 64 | // connection string and table are provided in OnInitialize() 65 | config.Initialize(); 66 | 67 | config.MaxDisplayListItems = 12; 68 | config.DebugMode = DebugModes.DeveloperErrorMessage; 69 | config.ApplicationName = "Changed"; 70 | config.SendAdminEmailConfirmations = true; 71 | 72 | // encrypted properties 73 | config.Password = "seekrit2"; 74 | config.AppConnectionString = "server=.;database=HRDatabase"; 75 | 76 | Assert.IsTrue(config.Write(), "Write Failed: " + config.ErrorMessage); 77 | 78 | // create a new instance and read the values from the database 79 | var config2 = new DatabaseConfiguration(); 80 | config2.Initialize(); 81 | 82 | Assert.IsNotNull(config2); 83 | Assert.AreEqual(config.MaxDisplayListItems, config2.MaxDisplayListItems); 84 | Assert.AreEqual(config.DebugMode, config2.DebugMode); 85 | 86 | // Encrypted values 87 | Assert.AreEqual(config.Password, config2.Password); 88 | Assert.AreEqual(config.AppConnectionString, config2.AppConnectionString); 89 | 90 | // reset to default val 91 | config.MaxDisplayListItems = 15; 92 | config.Write(); 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/js/bootstrap-dropdown.js: -------------------------------------------------------------------------------- 1 | /* ============================================================ 2 | * bootstrap-dropdown.js v2.0.4 3 | * http://twitter.github.com/bootstrap/javascript.html#dropdowns 4 | * ============================================================ 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ============================================================ */ 19 | 20 | 21 | !function ($) { 22 | "use strict"; // jshint ;_; 23 | 24 | 25 | /* DROPDOWN CLASS DEFINITION 26 | * ========================= */ 27 | 28 | var toggle = '[data-toggle="dropdown"]' 29 | , Dropdown = function (element) { 30 | var $el = $(element).on('click.dropdown.data-api', this.toggle) 31 | $('html').on('click.dropdown.data-api', function () { 32 | $el.parent().removeClass('open') 33 | }) 34 | } 35 | 36 | Dropdown.prototype = { 37 | 38 | constructor: Dropdown 39 | 40 | , toggle: function (e) { 41 | console.log('toggle'); 42 | var $this = $(this) 43 | , $parent 44 | , selector 45 | , isActive 46 | 47 | if ($this.is('.disabled, :disabled')) return 48 | 49 | selector = $this.attr('data-target') 50 | 51 | if (!selector) { 52 | selector = $this.attr('href') 53 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 54 | } 55 | 56 | $parent = $(selector) 57 | $parent.length || ($parent = $this.parent()) 58 | 59 | isActive = $parent.hasClass('open') 60 | 61 | //clearMenus(); 62 | 63 | if (!isActive) 64 | $parent.toggleClass('open'); 65 | 66 | 67 | return false; 68 | } 69 | 70 | } 71 | 72 | function clearMenus() { 73 | $(toggle).parent().removeClass('open') 74 | } 75 | 76 | 77 | /* DROPDOWN PLUGIN DEFINITION 78 | * ========================== */ 79 | 80 | $.fn.dropdown = function (option) { 81 | return this.each(function () { 82 | var $this = $(this) 83 | , data = $this.data('dropdown') 84 | if (!data) $this.data('dropdown', (data = new Dropdown(this))) 85 | if (typeof option == 'string') data[option].call($this) 86 | }) 87 | } 88 | 89 | $.fn.dropdown.Constructor = Dropdown 90 | 91 | 92 | /* APPLY TO STANDARD DROPDOWN ELEMENTS 93 | * =================================== */ 94 | 95 | $(function () { 96 | $('html').on('click.dropdown.data-api', clearMenus) 97 | $('body') 98 | .on('click.dropdown', '.dropdown form', function (e) { e.stopPropagation() }) 99 | .on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) 100 | }) 101 | 102 | }(window.jQuery); -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/JsonFileConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.IO; 4 | 5 | namespace Westwind.Utilities.Configuration.Tests 6 | { 7 | /// 8 | /// Tests default config file implementation that uses 9 | /// only base constructor behavior - (config file and section config only) 10 | /// 11 | [TestClass] 12 | public class JsonFileConfigurationTests 13 | { 14 | /// 15 | /// Note: For Web Apps this should be a complete path. 16 | /// Here the filename references the current directory 17 | /// 18 | public const string STR_JSONCONFIGFILE = "JsonConfiguration.txt"; 19 | 20 | 21 | [TestMethod] 22 | public void DefaultConstructorInstanceTest() 23 | { 24 | var config = new JsonFileConfiguration(); 25 | config.Initialize(configData: STR_JSONCONFIGFILE); 26 | 27 | Assert.IsNotNull(config); 28 | Assert.IsFalse(string.IsNullOrEmpty(config.ApplicationName)); 29 | 30 | string text = File.ReadAllText(STR_JSONCONFIGFILE); 31 | Console.WriteLine(text); 32 | } 33 | 34 | [TestMethod] 35 | public void WriteConfigurationTest() 36 | { 37 | File.Delete(STR_JSONCONFIGFILE); 38 | 39 | var config = new JsonFileConfiguration(); 40 | config.Initialize(STR_JSONCONFIGFILE); 41 | 42 | config.MaxDisplayListItems = 12; 43 | config.DebugMode = DebugModes.DeveloperErrorMessage; 44 | config.ApplicationName = "Changed"; 45 | config.SendAdminEmailConfirmations = true; 46 | 47 | // secure properties 48 | config.Password = "seekrit2"; 49 | config.AppConnectionString = "server=.;database=unsecured"; 50 | 51 | config.License.Company = "West Wind 3"; 52 | config.License.LicenseKey = "RickWestWind3-61123222"; 53 | 54 | config.Write(); 55 | 56 | string jsonConfig = File.ReadAllText(STR_JSONCONFIGFILE); 57 | Console.WriteLine(jsonConfig); 58 | 59 | Assert.IsTrue(jsonConfig.Contains(@"""DebugMode"": ""DeveloperErrorMessage""")); 60 | Assert.IsTrue(jsonConfig.Contains(@"""MaxDisplayListItems"": 12") ); 61 | Assert.IsTrue(jsonConfig.Contains(@"""SendAdminEmailConfirmations"": true")); 62 | 63 | // Password and AppSettings should be encrypted in config file 64 | Assert.IsTrue(jsonConfig.Contains(@"""Password"": ""ADoCNO6L1HIm8V7TyI4deg==""")); 65 | 66 | } 67 | 68 | [TestMethod] 69 | public void WriteEncryptedConfigurationTest() 70 | { 71 | File.Delete(STR_JSONCONFIGFILE); 72 | 73 | var config = new JsonFileConfiguration(); 74 | config.Initialize(STR_JSONCONFIGFILE); 75 | 76 | // write secure properties 77 | config.Password = "seekrit2"; 78 | config.AppConnectionString = "server=.;database=unsecured"; 79 | 80 | config.License.Company = "West Wind 2"; 81 | config.License.LicenseKey = "RickWestWind2-51123222"; 82 | 83 | config.Write(); 84 | 85 | // completely reload settings 86 | config = new JsonFileConfiguration(); 87 | config.Initialize(STR_JSONCONFIGFILE); 88 | 89 | Assert.IsTrue(config.Password == "seekrit2"); 90 | Assert.IsTrue(config.License.Company == "West Wind 2"); 91 | Assert.IsTrue(config.License.LicenseKey == "RickWestWind2-51123222"); 92 | 93 | string jsonConfig = File.ReadAllText(STR_JSONCONFIGFILE); 94 | Console.WriteLine(jsonConfig); 95 | 96 | // Password and AppSettings should be encrypted in config file 97 | Assert.IsTrue(jsonConfig.Contains(@"""Password"": ""ADoCNO6L1HIm8V7TyI4deg==""")); 98 | 99 | // now re-read settings into a new object 100 | var config2 = new JsonFileConfiguration(); 101 | config2.Initialize(STR_JSONCONFIGFILE); 102 | 103 | // check secure properties 104 | Assert.IsTrue(config.Password == "seekrit2"); 105 | Assert.IsTrue(config.AppConnectionString == "server=.;database=unsecured"); 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Controllers/SamplesViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Reflection; 3 | using System.Text; 4 | using System.Web.UI; 5 | using ApplicationConfigurationWeb; 6 | using Westwind.Utilities; 7 | 8 | namespace ApplicationConfigurationMvc.Controllers 9 | { 10 | public class SamplesViewModel 11 | { 12 | public ApplicationConfiguration Configuration { get; set; } 13 | public string ConfigTypeSelection { get; set; } 14 | public SamplesController Controller { get; set; } 15 | public string ErrorMessage { get; set; } 16 | public string InfoMessage { get; set; } 17 | 18 | public SamplesViewModel() 19 | { 20 | Configuration = App.Configuration; 21 | ConfigTypeSelection = "Default Web.Config"; 22 | } 23 | 24 | public string ShowPropertyGrid() 25 | { 26 | return ShowPropertyGrid(Configuration); 27 | } 28 | 29 | /// 30 | /// Creates a simplistic Property Grid to display of an object 31 | /// 32 | /// 33 | public static string ShowPropertyGrid(object sourceObject) 34 | { 35 | if (sourceObject == null) 36 | return "
No object passed.
"; 37 | 38 | StringBuilder sb = new StringBuilder(); 39 | using (StringWriter sw = new StringWriter(sb)) 40 | { 41 | using (HtmlTextWriter hWriter = new HtmlTextWriter(sw)) 42 | { 43 | hWriter.WriteBeginTag("table"); 44 | hWriter.WriteAttribute("border", "1"); 45 | hWriter.WriteAttribute("cellpadding", "5"); 46 | hWriter.WriteAttribute("class", "table table-bordered table-striped"); 47 | hWriter.Write(" style='border-collapse:collapse;'"); 48 | hWriter.Write(HtmlTextWriter.TagRightChar); 49 | MemberInfo[] miT = sourceObject.GetType().FindMembers(MemberTypes.Field | MemberTypes.Property, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, null); 50 | foreach (MemberInfo Field in miT) 51 | { 52 | string Name = Field.Name; 53 | object Value = null; 54 | if (Field.MemberType == MemberTypes.Field) 55 | { 56 | Value = ((FieldInfo)Field).GetValue(sourceObject); 57 | continue; 58 | } 59 | else 60 | if (Field.MemberType == MemberTypes.Property) 61 | Value = ((PropertyInfo)Field).GetValue(sourceObject, null); 62 | hWriter.WriteFullBeginTag("tr"); 63 | hWriter.WriteFullBeginTag("td"); 64 | hWriter.Write(Name); 65 | hWriter.WriteEndTag("td"); 66 | hWriter.WriteLine(); 67 | hWriter.WriteFullBeginTag("td"); 68 | hWriter.WriteBeginTag("input"); 69 | hWriter.WriteAttribute("name", "Configuration." + Name); 70 | hWriter.WriteAttribute("value", ReflectionUtils.TypedValueToString(Value)); 71 | hWriter.Write(" style='Width:400px' "); 72 | hWriter.Write(HtmlTextWriter.TagRightChar); 73 | hWriter.WriteEndTag("td"); 74 | hWriter.WriteLine(); 75 | hWriter.WriteEndTag("tr"); 76 | hWriter.WriteLine(); 77 | } 78 | hWriter.WriteEndTag("table"); 79 | //string TableResult = sb.ToString(); 80 | hWriter.Close(); 81 | } 82 | sw.Close(); 83 | } 84 | 85 | return sb.ToString(); 86 | } 87 | 88 | public void ShowError(string errorMessage) 89 | { 90 | this.ErrorMessage = errorMessage; 91 | } 92 | 93 | public void ShowMessage(string message) 94 | { 95 | this.InfoMessage = message; 96 | } 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Westwind.Utilities.Configuration.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1D865318-2863-4424-B650-58F220439D64} 8 | Library 9 | Properties 10 | Westwind.Utilities.Configuration 11 | Westwind.Utilities.Configuration 12 | v4.0 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | bin\Debug\Westwind.Utilities.Configuration.XML 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | false 33 | bin\Release\Westwind.Utilities.Configuration.XML 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | True 51 | True 52 | Resources.resx 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | PublicResXFileCodeGenerator 74 | Resources.Designer.cs 75 | 76 | 77 | 78 | 79 | copy $(TargetPath) ..\..\..\lib 80 | copy $(TargetDir)$(TargetName).xml ..\..\..\lib 81 | 82 | 89 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/XmlFileConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.IO; 4 | 5 | namespace Westwind.Utilities.Configuration.Tests 6 | { 7 | /// 8 | /// Tests default config file implementation that uses 9 | /// only base constructor behavior - (config file and section config only) 10 | /// 11 | [TestClass] 12 | public class XmlConfigurationTests 13 | { 14 | 15 | private TestContext testContextInstance; 16 | 17 | /// 18 | ///Gets or sets the test context which provides 19 | ///information about and functionality for the current test run. 20 | /// 21 | public TestContext TestContext 22 | { 23 | get 24 | { 25 | return testContextInstance; 26 | } 27 | set 28 | { 29 | testContextInstance = value; 30 | } 31 | } 32 | 33 | /// 34 | /// Note: For Web Apps this should be a complete path. 35 | /// Here the filename references the current directory 36 | /// 37 | public const string STR_XMLCONFIGFILE = "XmlConfiguration.xml"; 38 | 39 | 40 | [TestMethod] 41 | public void DefaultConstructorInstanceTest() 42 | { 43 | var config = new XmlFileConfiguration(); 44 | config.Initialize(configData: STR_XMLCONFIGFILE); 45 | 46 | Assert.IsNotNull(config); 47 | Assert.IsFalse(string.IsNullOrEmpty(config.ApplicationName)); 48 | 49 | string text = File.ReadAllText(STR_XMLCONFIGFILE); 50 | Console.WriteLine(text); 51 | } 52 | 53 | [TestMethod] 54 | public void WriteConfigurationTest() 55 | { 56 | var config = new XmlFileConfiguration(); 57 | config.Initialize(STR_XMLCONFIGFILE); 58 | 59 | config.MaxDisplayListItems = 12; 60 | config.DebugMode = DebugModes.DeveloperErrorMessage; 61 | config.ApplicationName = "Changed"; 62 | config.SendAdminEmailConfirmations = true; 63 | 64 | // secure properties 65 | config.Password = "seekrit2"; 66 | config.AppConnectionString = "server=.;database=unsecured"; 67 | 68 | config.License.LicenseKey = "asdss"; 69 | 70 | config.Write(); 71 | 72 | string xmlConfig = File.ReadAllText(STR_XMLCONFIGFILE); 73 | Console.WriteLine(xmlConfig); 74 | 75 | Assert.IsTrue(xmlConfig.Contains(@"DeveloperErrorMessage")); 76 | Assert.IsTrue(xmlConfig.Contains(@"12")); 77 | Assert.IsTrue(xmlConfig.Contains(@"true")); 78 | 79 | // Password and AppSettings should be encrypted in config file 80 | Assert.IsTrue(xmlConfig.Contains(@"ADoCNO6L1HIm8V7TyI4deg==")); 81 | Assert.IsTrue(xmlConfig.Contains(@"z6+T5mzXbtJBEgWqpQNYbBss0csbtw2b/qdge7PUixE=")); 82 | } 83 | 84 | [TestMethod] 85 | public void WriteEncryptedConfigurationTest() 86 | { 87 | var config = new XmlFileConfiguration(); 88 | config.Initialize(STR_XMLCONFIGFILE); 89 | 90 | // write secure properties 91 | config.Password = "seekrit2"; 92 | config.AppConnectionString = "server=.;database=unsecured"; 93 | 94 | config.Write(); 95 | 96 | string xmlConfig = File.ReadAllText(STR_XMLCONFIGFILE); 97 | Console.WriteLine(xmlConfig); 98 | 99 | // Password and AppSettings should be encrypted in config file 100 | Assert.IsTrue(xmlConfig.Contains(@"ADoCNO6L1HIm8V7TyI4deg==")); 101 | Assert.IsTrue(xmlConfig.Contains(@"z6+T5mzXbtJBEgWqpQNYbBss0csbtw2b/qdge7PUixE=")); 102 | 103 | // now re-read settings into a new object 104 | var config2 = new XmlFileConfiguration(); 105 | config2.Initialize(STR_XMLCONFIGFILE); 106 | 107 | // check secure properties 108 | Assert.IsTrue(config.Password == "seekrit2"); 109 | Assert.IsTrue(config.AppConnectionString == "server=.;database=unsecured"); 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | #West Wind Application Configuration Change Log 2 | 3 | ### Version 2.25 4 | *Oct. 14th, 2014* 5 | 6 | * **ConfigurationFile Configuration Provider support for Complex Types**
7 | Added another option for serialization of flat complex objects, by 8 | implementing additional checks for a **static** FromString() method that 9 | if found can be used to deserialize object. [more info](http://west-wind.com/westwindtoolkit/docs/?page=_1cx0ymket.htm) 10 | 11 | * **ConfigurationFile Configuration Provider support for IList**
12 | You can now also serialize IList objects into the config file. The list 13 | is serialize a ItemList1,ItemList2,ItemList3 where ItemList is the name 14 | of the property. Complex objects are supported with the new complex 15 | type parsing support or TypeConverters. [more info](http://west-wind.com/westwindtoolkit/docs/?page=_1cx0ymket.htm) 16 | 17 | * **Support for nested Configuration Property Encryption**
18 | You can now specify nested properties in child objects to be encrypted in 19 | all providers by using simple '.' syntax in the PropertiesToEncrypt property 20 | of the provider (ie. PropertiesToEncrypt="Password,License.LicenseKey"). 21 | 22 | 23 | ### Version 2.20 24 | *June. 13th, 2014* 25 | 26 | * **JSON File Provider added**
27 | You can now store configuration optionally using JSON. The new JsonFileConfigurationProvider 28 | uses JSON.NET to provide JSON configuration output. JSON.NET is dynamically linked so 29 | there's no hard dependency on it. If you use this provider make sure JSON.NET is added 30 | to your project. 31 | 32 | * **Updated Documentation** 33 | Added this changelog as well as updating the [detailed help file documentation](http://west-wind.com/westwind.applicationconfiguration/docs) step by step instructions. 34 | 35 | 36 | ###Version 2.15 37 | *Nov. 14th, 2013* 38 | 39 | * **Make XML Config File Reader read-only**
40 | Changed the config file reader to open files in read-only mode to minimze multi-user/thread access issues while writing configuration in case other threads want to access the data. Thanks to Patrick Wyatt. 41 | 42 | * **Fix XmlConfig Encryption Error**
43 | Fixed small bug that failed to decrypt encoded properties after writing out XmlFile properties to disk. Thanks to Patrick Wyatt. 44 | 45 | * **Several minor bug fixes**
46 | Fix issue configuration file issue in one of the AutoConfig file tests. Fix a small, config section reader issue. 47 | 48 | * **Fixed documentation**
49 | Accidentally left outdated V1 documentation on the detailed developer documentation site. Fixed. 50 | 51 | 52 | ###Version 2.10 53 | *August 25th, 2013* 54 | 55 | * **License Change - drop commercial License Requirement**
56 | We've dropped the requirement for a commercial license for this tool and are using a pure MIT license, 57 | with an *optional* commercial license available for those that want official support, require a 58 | commercial license in their organization or simply want to support this project. 59 | 60 | * **Documentation Updates**
61 | The documentation both on GitHub and in the online/chm help files have been updated significantly to provide a host more examples. 62 | 63 | * **Minor Bug fixes**
64 | Fixed a number of small issues with the configuration file and Sql providers. See GitHub commit history for more info. 65 | 66 | 67 | ###Version 2.00 68 | *January 14th, 2013* 69 | 70 | * **Simplified Instantiation Management**
71 | Changed the way the class initializes by explicitly requiring a call to Initialize() after instantiation. This removes any requirements to implement specific subclass methods on the configuration class making it much simpler to get started. 72 | 73 | * **Easier Customization of default Configuration Provider**
74 | If you need to customize the default configuration store for your configuration class you can now simply override the new <>OnCreateDefaultProvider()<> method. This method can create an instance of a provider and customize it as needed and simply return it. There's also a new OnInitialize() method which can take over the entire initial provider load and read process under your full control. 75 | 76 | * **Improved Auto-Creation Logic**
77 | Configuration stores are now automatically created if they don't exist yet - assuming the calling application has rights to write the file/store. On first read AppConfiguration checks if the store exists and if it doesn't tries to create it. If the store does exist, but keys are missing the keys are added and written to the store. 78 | 79 | * **Added additional Unit Tests**
80 | Added a host of new unit tests to demonstrate Configuration class implementations for each configuration provider type and usage examples. Updated existing examples to the new initialization syntax. 81 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/AppConfiguration.cd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | AQAAAAAAAAAEAQAAAAAIAAAgAAACAAAAAAAAAAEAAAI= 22 | AppConfiguration.cs 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | AQBBAYAAAYAQAQAAAAAAAAAgAAAAAAAAAAAAIQEAAAE= 35 | ConfigurationProviderBase.cs 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | QAAAAAAAgAAAAAAAAAAAAAAgAAASAAAAAAAAAAEAAAA= 54 | XmlFileConfigurationProvider.cs 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | AAABAAAIQAAACAAAAAAAgAAoAAAAAQAAAAAAAAEAAAA= 64 | ConfigurationFileConfigurationProvider.cs 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | CAAAAAACAAAAAAQAAAAAgAAgAAAgAAAAACAAAQEQAAA= 82 | SqlServerConfigurationProvider.cs 83 | 84 | 85 | 86 | 87 | 88 | AgAAAAAAAAAAACAAAAAAEAAAAAAAAAAAAAAAAAAAAAI= 89 | AppConfiguration.cs 90 | 91 | 92 | 93 | 94 | 95 | AAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAEAAAAAAEAAAA= 96 | StringConfigurationProvider.cs 97 | 98 | 99 | 100 | 101 | 102 | AQAAAYAAAYAAAQAAAAAAAAAgAAAAAAAAAAAAAQEAAAA= 103 | IConfigurationProvider.cs 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/Models/Entities/WebStoreContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | 8 | namespace Westwind.Data.Test.Models 9 | { 10 | public class WebStoreContext : DbContext // use to get support for DbNative interface 11 | { 12 | public DbSet Customers { get; set; } 13 | public DbSet Orders { get; set; } 14 | public DbSet LineItems { get; set; } 15 | 16 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 17 | { 18 | base.OnModelCreating(modelBuilder); 19 | } 20 | } 21 | 22 | public class WebStoreContextInitializer : DropCreateDatabaseIfModelChanges 23 | { 24 | protected override void Seed(WebStoreContext context) 25 | { 26 | try 27 | { 28 | var cust = new Customer() 29 | { 30 | FirstName = "Rick", 31 | LastName = "Strahl", 32 | Company = "West Wind", 33 | Address = "32 Kaiea Place\r\nPaia, HI", 34 | }; 35 | context.Customers.Add(cust); 36 | 37 | int res = context.SaveChanges(); 38 | 39 | var order = new Order() 40 | { 41 | Customer = cust, 42 | OrderId = "Order1", 43 | }; 44 | 45 | var lItem = new LineItem() 46 | { 47 | Sku = "WCONNECT", 48 | Description = "West wind Web Connection", 49 | Quantity = 1, 50 | Price = 399.99M, 51 | OrderId = order.Id 52 | }; 53 | lItem.Total = lItem.Quantity * lItem.Price; 54 | order.LineItems.Add(lItem); 55 | 56 | lItem = new LineItem() 57 | { 58 | Sku = "WWHELP", 59 | Description = "West Wind Html Help Builder", 60 | Quantity = 1, 61 | Price = 299.99M, 62 | OrderId = order.Id 63 | }; 64 | lItem.Total = lItem.Quantity * lItem.Price; 65 | order.LineItems.Add(lItem); 66 | 67 | context.Orders.Add(order); 68 | 69 | res = context.SaveChanges(); 70 | 71 | // add 100 random customers 72 | for (int i = 0; i < 550; i++) 73 | { 74 | cust = new Customer() 75 | { 76 | FirstName = RandomString(20), 77 | LastName = RandomString(20), 78 | Company = RandomString(25), 79 | Updated = DateTime.Now.AddDays( i * -1) 80 | }; 81 | 82 | order = new Order() 83 | { 84 | Entered = DateTime.Now.AddDays(i * -1), 85 | OrderId = RandomString(10) 86 | }; 87 | cust.Orders.Add(order); 88 | 89 | lItem = new LineItem() 90 | { 91 | Sku = "WCONNECT", 92 | Description = "West wind Web Connection", 93 | Quantity = 1, 94 | Price = 399.99M, 95 | OrderId = order.Id 96 | }; 97 | lItem.Total = lItem.Quantity * lItem.Price; 98 | order.LineItems.Add(lItem); 99 | 100 | lItem = new LineItem() 101 | { 102 | Sku = "WWHELP", 103 | Description = "West Wind Html Help Builder", 104 | Quantity = 1, 105 | Price = 299.99M, 106 | OrderId = order.Id 107 | }; 108 | lItem.Total = lItem.Quantity * lItem.Price; 109 | order.LineItems.Add(lItem); 110 | 111 | context.Customers.Add(cust); 112 | 113 | context.SaveChanges(); 114 | } 115 | 116 | 117 | 118 | 119 | } 120 | catch (Exception ex) 121 | { 122 | string message = ex.Message; 123 | } 124 | //base.Seed(context); 125 | } 126 | 127 | private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden 128 | 129 | private string RandomString(int size) 130 | { 131 | StringBuilder builder = new StringBuilder(); 132 | char ch; 133 | for (int i = 0; i < size; i++) 134 | { 135 | ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))); 136 | builder.Append(ch); 137 | } 138 | 139 | return builder.ToString(); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 |
9 |
10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/StringConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.IO; 4 | 5 | namespace Westwind.Utilities.Configuration.Tests 6 | { 7 | /// 8 | /// Tests implementation of the string provider. 9 | /// 10 | /// String providers make it easy to read and write 11 | /// configuration values and store them in any source 12 | /// that can store strings. For example you can store 13 | /// the xml generated in a database field of your choice. 14 | /// (there is a database field provider that does that 15 | /// however). 16 | /// 17 | /// Use App.Configuration.Read(xmlString) 18 | /// and App.Configuration.WriteAsString() to read and 19 | /// write the XML configuration data for storage in 20 | /// any non-existing format you like. 21 | /// 22 | /// Light weight alternative to creating your own 23 | /// configuration provider (although it's easy to 24 | /// create one). 25 | /// 26 | [TestClass] 27 | public class StringConfigurationTests 28 | { 29 | 30 | private TestContext testContextInstance; 31 | 32 | /// 33 | ///Gets or sets the test context which provides 34 | ///information about and functionality for the current test run. 35 | /// 36 | public TestContext TestContext 37 | { 38 | get 39 | { 40 | return testContextInstance; 41 | } 42 | set 43 | { 44 | testContextInstance = value; 45 | } 46 | } 47 | 48 | /// 49 | /// Write out configuration settings to string 50 | /// 51 | [TestMethod] 52 | public void WriteConfigurationTest() 53 | { 54 | var config = new StringConfiguration(); 55 | config.Initialize(null); 56 | 57 | config.MaxDisplayListItems = 12; 58 | config.DebugMode = DebugModes.DeveloperErrorMessage; 59 | config.ApplicationName = "Changed"; 60 | config.SendAdminEmailConfirmations = true; 61 | 62 | // secure properties 63 | config.Password = "seekrit2"; 64 | config.AppConnectionString = "server=.;database=unsecured"; 65 | 66 | string xmlConfig = config.WriteAsString(); 67 | 68 | Console.WriteLine(xmlConfig); 69 | 70 | Assert.IsTrue(xmlConfig.Contains(@"DeveloperErrorMessage")); 71 | Assert.IsTrue(xmlConfig.Contains(@"12")); 72 | Assert.IsTrue(xmlConfig.Contains(@"true")); 73 | 74 | // Password and AppSettings should be encrypted in config file 75 | Assert.IsTrue(xmlConfig.Contains(@"ADoCNO6L1HIm8V7TyI4deg==")); 76 | Assert.IsTrue(xmlConfig.Contains(@"z6+T5mzXbtJBEgWqpQNYbBss0csbtw2b/qdge7PUixE=")); 77 | } 78 | 79 | /// 80 | /// Unlike other providers the string provider has 81 | /// no 'automatic' read mode - it requires a string 82 | /// as input to work. 83 | /// 84 | [TestMethod] 85 | public void ReadConfigurationFromStringTest() 86 | { 87 | string xmlConfig = @" 88 | 89 | Configuration Tests 90 | Default 91 | 12 92 | false 93 | ADoCNO6L1HIm8V7TyI4deg== 94 | z6+T5mzXbtJBEgWqpQNYbBss0csbtw2b/qdge7PUixE= 95 | 96 | "; 97 | var config = new StringConfiguration(); 98 | 99 | // Initialize with configData as parameter to load from 100 | config.Initialize(configData: xmlConfig); 101 | 102 | Assert.IsNotNull(config); 103 | Assert.IsFalse(string.IsNullOrEmpty(config.ApplicationName)); 104 | Assert.IsTrue(config.MaxDisplayListItems == 12); 105 | Assert.AreEqual(config.Password, "seekrit2"); 106 | } 107 | 108 | 109 | [TestMethod] 110 | public void WriteEncryptedConfigurationTest() 111 | { 112 | var config = new StringConfiguration(); 113 | config.Initialize(); 114 | 115 | // write secure properties 116 | config.Password = "seekrit2"; 117 | config.AppConnectionString = "server=.;database=unsecured"; 118 | 119 | var xml = config.WriteAsString(); 120 | 121 | Console.WriteLine(xml); 122 | 123 | // Password and AppSettings should be encrypted in config file 124 | Assert.IsTrue(xml.Contains(@"ADoCNO6L1HIm8V7TyI4deg==")); 125 | Assert.IsTrue(xml.Contains(@"z6+T5mzXbtJBEgWqpQNYbBss0csbtw2b/qdge7PUixE=")); 126 | 127 | // now re-read settings into a new object 128 | var config2 = new StringConfiguration(); 129 | // pass XML to deserialize from - OnInitialize() implements this logic 130 | //config2.Initialize(xml); // same as below 131 | config2.Initialize(configData: xml); 132 | 133 | 134 | // check secure properties 135 | Assert.IsTrue(config.Password == "seekrit2"); 136 | Assert.IsTrue(config.AppConnectionString == "server=.;database=unsecured"); 137 | } 138 | } 139 | } -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Views/Samples/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model ApplicationConfigurationMvc.Controllers.SamplesViewModel 2 | @{ 3 | ViewBag.Title = "Application Configuration Demo"; 4 | Layout = null; 5 | } 6 | 7 | 8 | 9 | 10 | @ViewBag.Title 11 | 12 | 13 | 14 | 15 | 16 | 17 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | @* 37 | 38 | 39 | 40 | *@ 41 | 42 | 43 | 44 | 61 | 62 |
63 | 64 | @if (!string.IsNullOrEmpty(Model.ErrorMessage)) 65 | { 66 |
67 | × 68 | @Model.ErrorMessage 69 |
70 | } 71 | @if (!string.IsNullOrEmpty(Model.InfoMessage)) 72 | { 73 |
74 | × 75 | @Html.Raw(Model.InfoMessage) 76 |
77 | } 78 | 79 |
80 | @Html.DropDownListFor(mod => mod.ConfigTypeSelection, 81 | new SelectListItem[] { 82 | new SelectListItem() { 83 | Value = "Default Web.Config", 84 | Text = "Default Web.Config" 85 | }, 86 | new SelectListItem() { 87 | Value = "Different Web.Config Section", 88 | Text = "Different Web.Config Section" 89 | }, 90 | new SelectListItem() { 91 | Value = "Different .Config File", 92 | Text = "Different .Config File" 93 | }, 94 | new SelectListItem() { 95 | Value = "Simple Xml File", 96 | Text = "Simple Xml File" 97 | }, 98 | new SelectListItem() { 99 | Value = "String", 100 | Text = "String" 101 | }, 102 | new SelectListItem() { 103 | Value = "Database", 104 | Text = "Database" 105 | }, 106 | }, new { onchange = "$('form').submit();" }) 107 | 108 | 109 |
110 | 111 | @Html.Raw(Model.ShowPropertyGrid()) 112 |
113 | 114 |
115 | 116 |

117 | 118 |

119 | 120 |
121 | 122 |
123 | 124 |
125 | 126 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | @* 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | *@ 148 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Controllers/Code/ApplicationConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Web.Security; 3 | using Westwind.Utilities.Configuration; 4 | 5 | namespace ApplicationConfigurationWeb 6 | { 7 | 8 | /// 9 | /// Application specific config class that holds global configuration values 10 | /// that are read and optionally persisted into a configuration store. 11 | /// 12 | public class ApplicationConfiguration : AppConfiguration 13 | { 14 | 15 | /// 16 | /// Override default provider creation by using custom options 17 | /// 18 | /// 19 | /// 20 | /// 21 | protected override IConfigurationProvider OnCreateDefaultProvider(string sectionName, object configData) 22 | { 23 | 24 | var provider = new ConfigurationFileConfigurationProvider() 25 | { 26 | // use the machine key to seed encoding key string or provide any other string 27 | EncryptionKey = MachineKey.Encode(new byte[] { 3, 233, 8, 11, 32, 44 }, 28 | MachineKeyProtection.Encryption), 29 | PropertiesToEncrypt = "MailServerPassword,ConnectionString", 30 | // Custom section - if not specified goes to AppSettings 31 | ConfigurationSection = "ApplicationConfiguration" 32 | }; 33 | 34 | return provider; 35 | 36 | // Example of Sql configuration 37 | //var provider = new SqlServerConfigurationProvider() 38 | //{ 39 | // FieldsToEncrypt = "MailServerPassword,ConnectionString", 40 | // EncryptKey = "secret", 41 | // ConnectionString = "DevSampleConnectionString", 42 | // Tablename = "Configuration", 43 | // Key = 1 44 | //}; 45 | // Example of external XML configuration - advantage: Supports complex object hierarchies 46 | //var provider = new XmlFileConfigurationProvider() 47 | //{ 48 | // FieldsToEncrypt = "MailServerPassword,ConnectionString", 49 | // EncryptKey = "secret", 50 | // XmlConfigurationFile = HttpContext.Current.Server.MapPath("~/Configuration.xml") 51 | //}; 52 | } 53 | 54 | // Define properties and defaults 55 | 56 | public ApplicationConfiguration() 57 | { 58 | ApplicationTitle = "Configuration Sample"; 59 | ApplicationSubTitle = "Making ASP.NET Easier to use"; 60 | ApplicationCookieName = "_ApplicationId"; 61 | } 62 | 63 | /// 64 | /// The main title of the Weblog 65 | /// 66 | public string ApplicationTitle {get; set; } 67 | 68 | 69 | /// 70 | /// The subtitle for the Web Log displayed on the banner 71 | /// 72 | public string ApplicationSubTitle {get; set; } 73 | 74 | 75 | /// 76 | /// Application Cookie name used for user tracking 77 | /// 78 | public string ApplicationCookieName {get; set; } 79 | 80 | 81 | #region System Settings 82 | /// 83 | /// The database connection string for this WebLog instance 84 | /// 85 | public string ConnectionString {get; set; } 86 | 87 | 88 | /// 89 | /// Determines how errors are displayed 90 | /// Default - ASP.NET Default behavior 91 | /// ApplicationErrorMessage - Application level error message 92 | /// DeveloperErrorMessage - StackTrace and full error info 93 | /// 94 | public DebugModes DebugMode {get; set; } 95 | 96 | /// 97 | /// Determines how many items are displayed per page in typical list displays 98 | /// 99 | public int MaxPageItems {get; set; } 100 | 101 | #endregion 102 | 103 | #region Email Settings 104 | 105 | /// 106 | /// The Email Address used to send out emails 107 | /// 108 | public string SenderEmailAddress {get; set; } 109 | 110 | 111 | /// 112 | /// The Name of the senders Email 113 | /// 114 | public string SenderEmailName {get; set; } 115 | 116 | /// 117 | /// Optional CC List for email confirmations to customers. 118 | /// 119 | public string MailCc {get; set; } 120 | 121 | 122 | /// 123 | /// Email address use for admin emails 124 | /// 125 | public string AdminEmailAddress {get; set; } 126 | 127 | /// 128 | /// Email name used for Admin emails 129 | /// 130 | public string AdminEmailName {get; set; } 131 | 132 | /// 133 | /// Determines whether administrative emails are sent if 134 | /// the email addresses are set 135 | /// 136 | public bool AdminSendEmails {get; set; } 137 | 138 | 139 | /// 140 | /// The IP address or domain name of the mail server 141 | /// used to send email notifications and admin 142 | /// alerts through 143 | /// 144 | public string MailServer {get; set; } 145 | 146 | 147 | /// 148 | /// Mail Server username if required 149 | /// 150 | public string MailServerUsername {get; set; } 151 | 152 | 153 | /// 154 | /// Mail Server password if required 155 | /// 156 | public string MailServerPassword { get; set; } 157 | 158 | #endregion 159 | } 160 | 161 | /// 162 | /// Different modes that errors are displayed in the application 163 | /// 164 | public enum DebugModes 165 | { 166 | Default, 167 | ApplicationErrorMessage, 168 | DeveloperErrorMessage 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Support/Utilities/StringSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | 7 | namespace Westwind.Utilities 8 | { 9 | /// 10 | /// A very simple flat object serializer that can be used 11 | /// for intra application serialization. It creates a very compact 12 | /// positional string of properties. 13 | /// Only serializes top level properties, with no nesting support 14 | /// and only simple properties or those with a type converter are 15 | /// supported. Complex properties or non-two way type convertered 16 | /// values are ignored. 17 | /// 18 | /// Creates strings in the format of: 19 | /// Rick|rstrahl@west-wind.com|1|True|3/29/2013 1:32:31 PM|1 20 | /// 21 | /// 22 | /// This component is meant for intra application serialization of 23 | /// very compact objects. A common use case is for state serialization 24 | /// for cookies or a Forms Authentication ticket to minimize the amount 25 | /// of space used - the output produced here contains only the actual 26 | /// data, no property info or validation like other serialization formats. 27 | /// Use only on small objects when size and speed matter otherwise use 28 | /// a JSON/XML/Binary serializer or the ASP.NET LosFormatter object. 29 | /// 30 | public static class StringSerializer 31 | { 32 | private const string Seperator_Replace_String = "-@-"; 33 | 34 | /// 35 | /// Serializes a flat object's properties into a String 36 | /// separated by a separator character/string. Only 37 | /// top level properties are serialized. 38 | /// 39 | /// 40 | /// Only serializes top level properties, with no nesting support 41 | /// and only simple properties or those with a type converter are 42 | /// 'serialized'. All other property types use ToString(). 43 | /// 44 | /// The object to serialize 45 | /// Optional separator character or string. Default is | 46 | /// 47 | public static string SerializeObject(object objectToSerialize, string separator = null) 48 | { 49 | if (separator == null) 50 | separator = "|"; 51 | 52 | if (objectToSerialize == null) 53 | return "null"; 54 | 55 | var properties = 56 | objectToSerialize.GetType() 57 | .GetProperties(BindingFlags.Instance | BindingFlags.Public); 58 | //.OrderBy(prop => prop.Name.ToLower()) 59 | //.ToArray(); 60 | 61 | var values = new List(); 62 | 63 | for (int i = 0; i < properties.Length; i++) 64 | { 65 | var pi = properties[i]; 66 | 67 | // don't store read/write-only data 68 | if (!pi.CanRead && !pi.CanWrite) 69 | continue; 70 | 71 | object value = pi.GetValue(objectToSerialize, null); 72 | 73 | string stringValue = "null"; 74 | if (value != null) 75 | { 76 | if (value is string) 77 | { 78 | stringValue = (string)value; 79 | if (stringValue.Contains(separator)) 80 | stringValue = stringValue.Replace(separator, Seperator_Replace_String); 81 | } 82 | else 83 | stringValue = ReflectionUtils.TypedValueToString(value, unsupportedReturn: "null"); 84 | } 85 | 86 | values.Add(stringValue); 87 | } 88 | 89 | if (values.Count < 0) 90 | // empty object (no properties) 91 | return string.Empty; 92 | 93 | return string.Join(separator, values.ToArray()); 94 | } 95 | 96 | /// 97 | /// Deserializes an object previously serialized by SerializeObject. 98 | /// 99 | /// 100 | /// 101 | /// 102 | /// 103 | public static object DeserializeObject(string serialized, Type type, string separator = null) 104 | { 105 | if (serialized == "null") 106 | return null; 107 | 108 | if (separator == null) 109 | separator = "|"; 110 | 111 | object inst = ReflectionUtils.CreateInstanceFromType(type); 112 | var properties = inst.GetType() 113 | .GetProperties(BindingFlags.Instance | BindingFlags.Public); 114 | //.OrderBy(prop => prop.Name.ToLower()) 115 | //.ToArray(); 116 | 117 | string[] tokens = serialized.Split(new string[] { separator }, StringSplitOptions.None); 118 | if (tokens == null || tokens.Length < 1) 119 | return null; 120 | 121 | for (int i = 0; i < properties.Length; i++) 122 | { 123 | string token = tokens[i]; 124 | var prop = properties[i]; 125 | 126 | // don't store read/write-only data 127 | if (!prop.CanRead && !prop.CanWrite) 128 | continue; 129 | 130 | token = token.Replace(Seperator_Replace_String, separator); 131 | 132 | object value = null; 133 | if (token != null) 134 | { 135 | try 136 | { 137 | value = ReflectionUtils.StringToTypedValue(token, prop.PropertyType); 138 | } 139 | catch (InvalidCastException) 140 | { 141 | // skip over unsupported types 142 | } 143 | } 144 | 145 | prop.SetValue(inst, value, null); 146 | } 147 | 148 | 149 | return inst; 150 | } 151 | 152 | /// 153 | /// Deserializes an object serialized with SerializeObject. 154 | /// 155 | /// 156 | /// 157 | /// 158 | /// 159 | public static T Deserialize(string serialized, string separator = null) 160 | where T : class, new() 161 | { 162 | return DeserializeObject(serialized, typeof(T), separator) as T; 163 | } 164 | } 165 | } -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/CustomConfigFileConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.IO; 4 | 5 | namespace Westwind.Utilities.Configuration.Tests 6 | { 7 | /// 8 | /// Tests default config file implementation that uses 9 | /// only base constructor behavior - (config file and section config only) 10 | /// 11 | [TestClass] 12 | public class CustomConfigurationTests 13 | { 14 | 15 | private TestContext testContextInstance; 16 | 17 | /// 18 | ///Gets or sets the test context which provides 19 | ///information about and functionality for the current test run. 20 | /// 21 | public TestContext TestContext 22 | { 23 | get 24 | { 25 | return testContextInstance; 26 | } 27 | set 28 | { 29 | testContextInstance = value; 30 | } 31 | } 32 | 33 | [TestMethod] 34 | public void DefaultConstructorInstanceTest() 35 | { 36 | var config = new CustomConfigFileConfiguration(); 37 | config.Initialize(); 38 | 39 | Assert.IsNotNull(config); 40 | Assert.IsFalse(string.IsNullOrEmpty(config.ApplicationName)); 41 | 42 | string text = File.ReadAllText(TestHelpers.GetTestConfigFilePath()); 43 | Assert.IsTrue(text.Contains(@"")); 44 | Console.WriteLine(text); 45 | } 46 | 47 | [TestMethod] 48 | public void WriteConfigurationTest() 49 | { 50 | File.Delete(TestHelpers.GetTestConfigFilePath()); 51 | 52 | var config = new CustomConfigFileConfiguration(); 53 | config.Initialize(); 54 | 55 | config.MaxDisplayListItems = 12; 56 | config.DebugMode = DebugModes.DeveloperErrorMessage; 57 | config.ApplicationName = "Changed"; 58 | config.SendAdminEmailConfirmations = true; 59 | 60 | // secure properties 61 | config.Password = "seekrit2"; 62 | config.AppConnectionString = "server=.;database=unsecured"; 63 | 64 | // Complex Types 65 | config.License.Company = "Updated Company"; 66 | config.ServerList[0] = "UpdatedServerName"; 67 | 68 | config.License.Name = "Rick"; 69 | config.License.Company = "West Wind 2"; 70 | config.License.LicenseKey = "RickWestWind2-51231223"; 71 | 72 | config.Write(); 73 | 74 | config = null; 75 | config = new CustomConfigFileConfiguration(); 76 | config.Initialize(); 77 | 78 | Console.WriteLine(config.License.LicenseKey); 79 | Assert.IsTrue(config.License.LicenseKey == "RickWestWind2-51231223"); 80 | 81 | 82 | string text = File.ReadAllText(TestHelpers.GetTestConfigFilePath()); 83 | Console.WriteLine(text); 84 | 85 | Assert.IsTrue(text.Contains(@"")); 86 | Assert.IsTrue(text.Contains(@"")); 87 | Assert.IsTrue(text.Contains(@"")); 88 | 89 | // Password and AppSettings should be encrypted in config file 90 | Assert.IsTrue(text.Contains(@"")); 91 | Assert.IsTrue(text.Contains(@"")); 92 | 93 | // Complex Value 94 | Assert.IsTrue(text.Contains(@"West Wind 2")); 95 | 96 | // List values 97 | Assert.IsTrue(text.Contains(@"")); 128 | Assert.IsTrue(text.Contains(@"")); 129 | Assert.IsTrue(text.Contains(@"")); 130 | 131 | // Password and AppSettings should be encrypted in config file 132 | Assert.IsTrue(text.Contains(@"")); 133 | Assert.IsTrue(text.Contains(@"")); 134 | 135 | // Complex Value 136 | Assert.IsTrue(text.Contains(@"Updated Company")); 137 | 138 | // List values 139 | Assert.IsTrue(text.Contains(@"")); 169 | Assert.IsTrue(text.Contains(@"")); 170 | 171 | // now re-read settings into a new object 172 | var config2 = new CustomConfigFileConfiguration(); 173 | config2.Initialize(); 174 | 175 | // check secure properties 176 | Assert.IsTrue(config.Password == "seekrit2"); 177 | Assert.IsTrue(config.AppConnectionString == "server=.;database=unsecured"); 178 | } 179 | } 180 | } -------------------------------------------------------------------------------- /.nuget/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\..\ 5 | 6 | 7 | false 8 | 9 | 10 | false 11 | 12 | 13 | true 14 | 15 | 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) 31 | 32 | 33 | 34 | 35 | $(SolutionDir).nuget 36 | 37 | 38 | 39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config 40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config 41 | 42 | 43 | 44 | $(MSBuildProjectDirectory)\packages.config 45 | $(PackagesProjectConfig) 46 | 47 | 48 | 49 | 50 | $(NuGetToolsPath)\NuGet.exe 51 | @(PackageSource) 52 | 53 | "$(NuGetExePath)" 54 | mono --runtime=v4.0.30319 $(NuGetExePath) 55 | 56 | $(TargetDir.Trim('\\')) 57 | 58 | -RequireConsent 59 | -NonInteractive 60 | 61 | "$(SolutionDir) " 62 | "$(SolutionDir)" 63 | 64 | 65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) 66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols 67 | 68 | 69 | 70 | RestorePackages; 71 | $(BuildDependsOn); 72 | 73 | 74 | 75 | 76 | $(BuildDependsOn); 77 | BuildPackage; 78 | 79 | 80 | 81 | 82 | 83 | 84 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 99 | 100 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Westwind.Utilities.Configuration.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | public class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | public static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Westwind.Utilities.Configuration.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | public static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to A connection string must be passed to the constructor. 65 | /// 66 | public static string AConnectionStringMustBePassedToTheConstructor { 67 | get { 68 | return ResourceManager.GetString("AConnectionStringMustBePassedToTheConstructor", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to Byte[] value greater than 20megs are not supported. 74 | /// 75 | public static string ByteValueGreaterThan20megsAreNotSupported { 76 | get { 77 | return ResourceManager.GetString("ByteValueGreaterThan20megsAreNotSupported", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// Looks up a localized string similar to This Configuration method is no longer supported. Use a Provider configuration instead.. 83 | /// 84 | public static string ConfigurationMethodNoLongerSupported { 85 | get { 86 | return ResourceManager.GetString("ConfigurationMethodNoLongerSupported", resourceCulture); 87 | } 88 | } 89 | 90 | /// 91 | /// Looks up a localized string similar to DataReader passed to DataReaderToObject cannot be closed. 92 | /// 93 | public static string DataReaderPassedToDataReaderToObjectCannot { 94 | get { 95 | return ResourceManager.GetString("DataReaderPassedToDataReaderToObjectCannot", resourceCulture); 96 | } 97 | } 98 | 99 | /// 100 | /// Looks up a localized string similar to Invalid Connection string name.. 101 | /// 102 | public static string InvalidConnectionStringName { 103 | get { 104 | return ResourceManager.GetString("InvalidConnectionStringName", resourceCulture); 105 | } 106 | } 107 | 108 | /// 109 | /// Looks up a localized string similar to Invalid encryption property name. 110 | /// 111 | public static string InvalidEncryptionPropertyName { 112 | get { 113 | return ResourceManager.GetString("InvalidEncryptionPropertyName", resourceCulture); 114 | } 115 | } 116 | 117 | /// 118 | /// Looks up a localized string similar to Invalid type for XmlType to .NET Type conversion.. 119 | /// 120 | public static string InvalidTypeForXmlTypeToNETTypeConversion { 121 | get { 122 | return ResourceManager.GetString("InvalidTypeForXmlTypeToNETTypeConversion", resourceCulture); 123 | } 124 | } 125 | 126 | /// 127 | /// Looks up a localized string similar to Invalid XML configuration file format in {0}.. 128 | /// 129 | public static string InvalidXmlConfigurationFile { 130 | get { 131 | return ResourceManager.GetString("InvalidXmlConfigurationFile", resourceCulture); 132 | } 133 | } 134 | 135 | /// 136 | /// Looks up a localized string similar to Object could not be deserialized from Xml.. 137 | /// 138 | public static string ObjectCouldNotBeDeserializedFromXml { 139 | get { 140 | return ResourceManager.GetString("ObjectCouldNotBeDeserializedFromXml", resourceCulture); 141 | } 142 | } 143 | 144 | /// 145 | /// Looks up a localized string similar to Type Conversion not handled in StringToTypedValue for . 146 | /// 147 | public static string StringToTypedValueValueTypeConversionFailed { 148 | get { 149 | return ResourceManager.GetString("StringToTypedValueValueTypeConversionFailed", resourceCulture); 150 | } 151 | } 152 | 153 | /// 154 | /// Looks up a localized string similar to Unable to read configuration string from Sql Server field.. 155 | /// 156 | public static string UnableToExtractKeys { 157 | get { 158 | return ResourceManager.GetString("UnableToExtractKeys", resourceCulture); 159 | } 160 | } 161 | 162 | /// 163 | /// Looks up a localized string similar to Unable to read config information from string.. 164 | /// 165 | public static string UnableToReadConfigDataFromString { 166 | get { 167 | return ResourceManager.GetString("UnableToReadConfigDataFromString", resourceCulture); 168 | } 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Unable to read config information from string. 122 | UnableToReadConfigDataFromString description 123 | 124 | 125 | Unable to read configuration string from Sql Server field. 126 | UnableToExtractKeys description 127 | 128 | 129 | This Configuration method is no longer supported. Use a Provider configuration instead. 130 | SetConfigurationSectionValueIsNoLongerSupported description 131 | 132 | 133 | Type Conversion not handled in StringToTypedValue for 134 | StringToTypedValueValueTypeConversionFailed description 135 | 136 | 137 | Invalid type for XmlType to .NET Type conversion. 138 | InvalidTypeForXmlTypeToNETTypeConversion description 139 | 140 | 141 | DataReader passed to DataReaderToObject cannot be closed 142 | DataReaderPassedToDataReaderToObjectCannot description 143 | 144 | 145 | Byte[] value greater than 20megs are not supported 146 | ByteValueGreaterThan20megsAreNotSupported description 147 | 148 | 149 | A connection string must be passed to the constructor 150 | AConnectionStringMustBePassedToTheConstructor description 151 | 152 | 153 | Invalid Connection string name. 154 | InvalidConnectionStringName description 155 | 156 | 157 | Object could not be deserialized from Xml. 158 | ObjectCouldNotBeDeserializedFromXml description 159 | 160 | 161 | Invalid encryption property name 162 | 163 | 164 | Invalid XML configuration file format in {0}. 165 | 166 | -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/AutoConfigFileConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.IO; 4 | using System.Configuration; 5 | 6 | namespace Westwind.Utilities.Configuration.Tests 7 | { 8 | /// 9 | /// Tests default config file implementation that uses 10 | /// only base constructor behavior - (config file and section config only) 11 | /// 12 | [TestClass] 13 | public class AutoConfigFileConfigurationTests 14 | { 15 | 16 | private TestContext testContextInstance; 17 | 18 | /// 19 | ///Gets or sets the test context which provides 20 | ///information about and functionality for the current test run. 21 | /// 22 | public TestContext TestContext 23 | { 24 | get 25 | { 26 | return testContextInstance; 27 | } 28 | set 29 | { 30 | testContextInstance = value; 31 | } 32 | } 33 | 34 | [TestMethod] 35 | public void DefaultConstructorInstanceTest() 36 | { 37 | var config = new AutoConfigFileConfiguration(); 38 | 39 | // gets .config file, AutoConfigFileConfiguration section 40 | config.Initialize(); 41 | 42 | Assert.IsNotNull(config); 43 | Assert.IsFalse(string.IsNullOrEmpty(config.ApplicationName)); 44 | Assert.AreEqual(config.MaxDisplayListItems, 15); 45 | 46 | string text = File.ReadAllText(TestHelpers.GetTestConfigFilePath()); 47 | Console.WriteLine(text); 48 | } 49 | 50 | [TestMethod] 51 | public void DefaultConstructorWithCustomProviderTest() 52 | { 53 | var config = new AutoConfigFileConfiguration(); 54 | 55 | // Create a customized provider to set provider options 56 | var provider = new ConfigurationFileConfigurationProvider() 57 | { 58 | ConfigurationSection = "CustomConfiguration", 59 | EncryptionKey = "seekrit123", 60 | PropertiesToEncrypt = "MailServer,MailServerPassword" 61 | }; 62 | 63 | config.Initialize(provider); 64 | 65 | // Config File and custom section should have been created in config file 66 | string text = File.ReadAllText(TestHelpers.GetTestConfigFilePath()); 67 | 68 | Assert.IsFalse(string.IsNullOrEmpty(text)); 69 | Assert.IsTrue(text.Contains("")); 70 | 71 | // MailServer/MailServerPassword value should be encrypted 72 | Console.WriteLine(text); 73 | } 74 | 75 | 76 | [TestMethod] 77 | public void DefaultConstructorWithAppSettingsProviderTest() 78 | { 79 | var config = new AutoConfigFileConfiguration(); 80 | 81 | // Create a customized provider to set provider options 82 | var provider = new ConfigurationFileConfigurationProvider() 83 | { 84 | ConfigurationSection = null, // forces to AppSettings 85 | EncryptionKey = "seekrit123", 86 | PropertiesToEncrypt = "MailServer,MailServerPassword" 87 | }; 88 | 89 | config.Initialize(provider); 90 | 91 | // Config File and custom section should have been created in config file 92 | string text = File.ReadAllText(TestHelpers.GetTestConfigFilePath()); 93 | 94 | Assert.IsFalse(string.IsNullOrEmpty(text)); 95 | Assert.IsTrue(text.Contains("")); 96 | 97 | // MailServer/MailServerPassword value should be encrypted 98 | Console.WriteLine(text); 99 | 100 | config.ApplicationName = "Updated Configuration"; 101 | config.Write(); 102 | 103 | config = null; 104 | config = new AutoConfigFileConfiguration(); 105 | config.Initialize(provider); 106 | 107 | config.Initialize(); // should reload, reread 108 | 109 | Console.WriteLine("Application Name: " + config.ApplicationName); 110 | 111 | Assert.IsTrue(config.ApplicationName == "Updated Configuration"); 112 | 113 | } 114 | 115 | [TestMethod] 116 | public void AutoConfigWriteConfigurationTest() 117 | { 118 | var config = new AutoConfigFileConfiguration(); 119 | config.Initialize(); 120 | 121 | Assert.IsNotNull(config); 122 | Assert.IsFalse(string.IsNullOrEmpty(config.ApplicationName)); 123 | Assert.AreEqual(config.MaxDisplayListItems, 15); 124 | 125 | config.MaxDisplayListItems = 17; 126 | config.Write(); 127 | 128 | var config2 = new AutoConfigFileConfiguration(); 129 | config2.Initialize(); 130 | 131 | Assert.AreEqual(config2.MaxDisplayListItems, 17); 132 | 133 | // reset to default val 134 | config2.MaxDisplayListItems = 15; 135 | config2.Write(); 136 | } 137 | 138 | [TestMethod] 139 | public void WriteConfigurationTest() 140 | { 141 | var config = new AutoConfigFileConfiguration(); 142 | config.Initialize(); 143 | 144 | config.MaxDisplayListItems = 12; 145 | config.DebugMode = DebugModes.DeveloperErrorMessage; 146 | config.ApplicationName = "Changed"; 147 | config.SendAdminEmailConfirmations = true; 148 | 149 | // update complex type 150 | config.License.Company = "Updated Company"; 151 | config.License.Name = "New User"; 152 | config.License.LicenseKey = "UpdatedCompanyNewUser-5331231"; 153 | 154 | config.Write(); 155 | 156 | string text = File.ReadAllText(TestHelpers.GetTestConfigFilePath()); 157 | Console.WriteLine(text); 158 | 159 | Assert.IsTrue(text.Contains(@"")); 160 | Assert.IsTrue(text.Contains(@"")); 161 | Assert.IsTrue(text.Contains(@"")); 162 | 163 | Assert.IsTrue(text.Contains(@"")); 164 | 165 | var config2 = new AutoConfigFileConfiguration(); 166 | config2.Initialize(); 167 | 168 | Assert.AreEqual(config2.MaxDisplayListItems, 12); 169 | Assert.AreEqual(config2.ApplicationName, "Changed"); 170 | Assert.AreEqual("Updated Company",config2.License.Company); 171 | 172 | // reset to default val 173 | config2.MaxDisplayListItems = 15; 174 | config2.Write(); 175 | } 176 | 177 | 178 | /// 179 | /// Test without explicit constructor parameter 180 | /// 181 | [TestMethod] 182 | public void DefaultConstructor2InstanceTest() 183 | { 184 | var config = new AutoConfigFile2Configuration(); 185 | 186 | // Not required since custom constructor calls this 187 | //config.Initialize(); 188 | 189 | Assert.IsNotNull(config); 190 | Assert.IsFalse(string.IsNullOrEmpty(config.ApplicationName)); 191 | Assert.AreEqual(config.MaxDisplayListItems, 15); 192 | 193 | string text = File.ReadAllText(TestHelpers.GetTestConfigFilePath()); 194 | Console.WriteLine(text); 195 | } 196 | 197 | /// 198 | /// Write test without explicit constructor 199 | /// 200 | [TestMethod] 201 | public void WriteConfiguration2Test() 202 | { 203 | var config = new AutoConfigFile2Configuration(); 204 | 205 | // not necesary since constructor calls internally 206 | //config.Initialize(); 207 | 208 | config.MaxDisplayListItems = 12; 209 | config.DebugMode = DebugModes.DeveloperErrorMessage; 210 | config.ApplicationName = "Changed"; 211 | config.SendAdminEmailConfirmations = true; 212 | config.Write(); 213 | 214 | string text = File.ReadAllText(TestHelpers.GetTestConfigFilePath()); 215 | Console.WriteLine(text); 216 | 217 | Assert.IsTrue(text.Contains(@"")); 218 | Assert.IsTrue(text.Contains(@"")); 219 | Assert.IsTrue(text.Contains(@"")); 220 | 221 | // reset to default val 222 | config.MaxDisplayListItems = 15; 223 | config.Write(); 224 | } 225 | } 226 | } -------------------------------------------------------------------------------- /Westwind.Utilities.Configuration.Tests/Westwind.Utilities.Configuration.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {7462B3A1-4894-4F1A-8B16-7B8D058EAC13} 7 | Library 8 | Properties 9 | Westwind.Utilities.Configuration.Tests 10 | Westwind.Utilities.Configuration.Tests 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | ..\ 21 | true 22 | 23 | 24 | true 25 | full 26 | false 27 | bin\Debug\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | false 41 | 42 | 43 | 44 | False 45 | ..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.dll 46 | 47 | 48 | False 49 | ..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.SqlServer.dll 50 | 51 | 52 | 53 | False 54 | ..\packages\Newtonsoft.Json.6.0.5\lib\net45\Newtonsoft.Json.dll 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | {1d865318-2863-4424-b650-58f220439d64} 104 | Westwind.Utilities.Configuration 105 | 106 | 107 | 108 | 109 | Always 110 | 111 | 112 | 113 | 114 | 115 | 116 | Always 117 | 118 | 119 | 120 | 121 | 122 | 123 | False 124 | 125 | 126 | False 127 | 128 | 129 | False 130 | 131 | 132 | False 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 143 | 144 | 145 | 146 | 153 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Css/bootstrap-responsive.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.0.4 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}@media(max-width:767px){.visible-phone{display:inherit!important}.hidden-phone{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(min-width:768px) and (max-width:979px){.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:18px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.modal{position:absolute;top:10px;right:10px;left:10px;width:auto;margin:0}.modal.fade.in{top:auto}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:auto;margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.762430939%;*margin-left:2.709239449638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:99.999999993%;*width:99.9468085036383%}.row-fluid .span11{width:91.436464082%;*width:91.38327259263829%}.row-fluid .span10{width:82.87292817100001%;*width:82.8197366816383%}.row-fluid .span9{width:74.30939226%;*width:74.25620077063829%}.row-fluid .span8{width:65.74585634900001%;*width:65.6926648596383%}.row-fluid .span7{width:57.182320438000005%;*width:57.129128948638304%}.row-fluid .span6{width:48.618784527%;*width:48.5655930376383%}.row-fluid .span5{width:40.055248616%;*width:40.0020571266383%}.row-fluid .span4{width:31.491712705%;*width:31.4385212156383%}.row-fluid .span3{width:22.928176794%;*width:22.874985304638297%}.row-fluid .span2{width:14.364640883%;*width:14.311449393638298%}.row-fluid .span1{width:5.801104972%;*width:5.747913482638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:714px}input.span11,textarea.span11,.uneditable-input.span11{width:652px}input.span10,textarea.span10,.uneditable-input.span10{width:590px}input.span9,textarea.span9,.uneditable-input.span9{width:528px}input.span8,textarea.span8,.uneditable-input.span8{width:466px}input.span7,textarea.span7,.uneditable-input.span7{width:404px}input.span6,textarea.span6,.uneditable-input.span6{width:342px}input.span5,textarea.span5,.uneditable-input.span5{width:280px}input.span4,textarea.span4,.uneditable-input.span4{width:218px}input.span3,textarea.span3,.uneditable-input.span3{width:156px}input.span2,textarea.span2,.uneditable-input.span2{width:94px}input.span1,textarea.span1,.uneditable-input.span1{width:32px}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:30px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.564102564%;*margin-left:2.510911074638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145300001%;*width:91.3997999636383%}.row-fluid .span10{width:82.905982906%;*width:82.8527914166383%}.row-fluid .span9{width:74.358974359%;*width:74.30578286963829%}.row-fluid .span8{width:65.81196581200001%;*width:65.7587743226383%}.row-fluid .span7{width:57.264957265%;*width:57.2117657756383%}.row-fluid .span6{width:48.717948718%;*width:48.6647572286383%}.row-fluid .span5{width:40.170940171000005%;*width:40.117748681638304%}.row-fluid .span4{width:31.623931624%;*width:31.5707401346383%}.row-fluid .span3{width:23.076923077%;*width:23.0237315876383%}.row-fluid .span2{width:14.529914530000001%;*width:14.4767230406383%}.row-fluid .span1{width:5.982905983%;*width:5.929714493638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:1160px}input.span11,textarea.span11,.uneditable-input.span11{width:1060px}input.span10,textarea.span10,.uneditable-input.span10{width:960px}input.span9,textarea.span9,.uneditable-input.span9{width:860px}input.span8,textarea.span8,.uneditable-input.span8{width:760px}input.span7,textarea.span7,.uneditable-input.span7{width:660px}input.span6,textarea.span6,.uneditable-input.span6{width:560px}input.span5,textarea.span5,.uneditable-input.span5{width:460px}input.span4,textarea.span4,.uneditable-input.span4{width:360px}input.span3,textarea.span3,.uneditable-input.span3{width:260px}input.span2,textarea.span2,.uneditable-input.span2{width:160px}input.span1,textarea.span1,.uneditable-input.span1{width:60px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:18px}.navbar-fixed-bottom{margin-top:18px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 9px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#999;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#222}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:block;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222;border-bottom:1px solid #222;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} 10 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | West Wind Application Configuration for .NET 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | 37 | 38 | 39 | 40 | 41 | 61 | 62 |
63 | 64 |
65 |
66 |
67 | 68 |
69 | 70 |
71 | 72 | 73 |

Application Configuration for .NET

74 |

75 | code-first, strongly typed configuration classes for your .NET applications 76 |

77 |

78 | Need to store common configuration settings in your application, but don't want to use the stodgy .NET configuration classes 79 | to access configuration data? This library lets you create .NET classes that map configuration data 80 | to strongly typed properties and retrieve\store these values either using the default .NET config 81 | file mechanism or various other configuration formats. 82 |

83 |

84 |

Features:

85 |

86 |
    87 |
  • Create strongly typed configuration classes
  • 88 |
  • Simply add properties to a class to map a configuration item
  • 89 |
  • Automatic type conversion for simple .NET types and enums
  • 90 |
  • Storage to .config files, plain XML or JSON files, strings or a database
  • 91 |
  • Read and write to configuration stores
  • 92 |
  • Automatically synch class configuration to config store
  • 93 |
  • Encrypt individual configuration keys rather than entire section
  • 94 |
  • Ability to create multiple configuration objects to isolate configuration data
  • 95 |
  • Extensible: Create your own configuration store providers
  • 96 |
  • Use in Web, Desktop, Services or Console applications
  • 97 |
98 |

99 | Learn more » 100 | 101 | 102 | 103 |

104 |

105 | 106 |

107 |
108 |
109 |
110 | 111 | 112 | 113 | 114 |
115 |
116 |

Learn

117 |

118 | Check out more information and view code examples on how to 119 | quickly create strongly typed configuration classes use them 120 | easily and efficiently from within your own applications. 121 |

122 |

Documentation »

123 |

Examples »

124 |
125 |
126 |

Get It!

127 |

128 | You can download this toolkit directly to get the compiled code and examples, 129 | or access the full source including the examples 130 | on GitHub. The easiest ways to use 131 | this toolkit however is to add it to your project via NuGet. 132 |

133 |

134 | Install from NuGet » 135 |

136 |

137 | Source on GitHub » 138 |

139 |

140 | Download Binaries » 141 |

142 |
143 |
144 |

License

145 |

146 | This toolkit is free and open source for use in any 147 | project or application. An optional commercial license is available 148 | for support, environments where full licensing is required or if you 149 | just want to support this project. 150 |

151 |

View license »

152 |

Buy a license »

153 |
154 |
155 | 156 | 157 |
158 | 159 |
160 |

© West Wind Technologies, 2012

161 |
162 | 163 |
164 | 165 | 166 | 167 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /Westwind.ApplicationConfiguration.WebSample/Westwind.ApplicationConfiguration.WebSample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | 2.0 10 | {2CEBB8E2-46F5-4716-A866-48B2A2E33206} 11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 12 | Library 13 | Properties 14 | ApplicationConfigurationSamples 15 | ApplicationConfigurationSamples 16 | v4.0 17 | false 18 | false 19 | 20 | 21 | 22 | 23 | ..\ 24 | true 25 | 26 | 27 | true 28 | full 29 | false 30 | bin\ 31 | DEBUG;TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | pdbonly 38 | true 39 | bin\ 40 | TRACE 41 | prompt 42 | 4 43 | false 44 | Encryption password is used only if any deployment setting is marked as secure 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | True 59 | ..\..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.Helpers.dll 60 | 61 | 62 | True 63 | ..\..\packages\Microsoft.AspNet.Mvc.3.0.20105.1\lib\net40\System.Web.Mvc.dll 64 | 65 | 66 | True 67 | ..\..\packages\Microsoft.AspNet.Razor.1.0.20105.408\lib\net40\System.Web.Razor.dll 68 | 69 | 70 | True 71 | ..\..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.dll 72 | 73 | 74 | True 75 | ..\..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.Deployment.dll 76 | 77 | 78 | True 79 | ..\..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.Razor.dll 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | Global.asax 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | bootstrap.js 119 | 120 | 121 | 122 | 123 | jquery.js 124 | 125 | 126 | 127 | Web.config 128 | 129 | 130 | Web.config 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | {1d865318-2863-4424-b650-58f220439d64} 149 | Westwind.Utilities.Configuration 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 10.0 160 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | True 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 181 | 182 | 183 | 184 | 190 | --------------------------------------------------------------------------------