I have to migrate a large .net 1.1 application to .net 3.5.
The system used Configuration Management Application Block (CMAB) to load config files starting with the app.config file as:
<configuration>
<configSections>
<section
name="applicationConfigurationManagement"
type="Microsoft.ApplicationBlocks.ConfigurationManagement.ConfigurationManagerSectionHandler,Microsoft.ApplicationBlocks.ConfigurationManagement, Version=1.0.0.0,Culture=neutral,PublicKeyToken=e64cb664730084d3" />
<section
name="MyAppSystemSettings"
type="Microsoft.ApplicationBlocks.ConfigurationManagement.XmlHashtableSectionHandler,Microsoft.ApplicationBlocks.ConfigurationManagement, Version=1.0.0.0,Culture=neutral,PublicKeyToken=e64cb664730084d3" />
</configSections>
<appSettings>
<!-- Key / Value Pairs -->
</appSettings>
<!-- ## Configuration Management Settings ## -->
<applicationConfigurationManagement defaultSection="MyAppSystemSettings">
<configSection name="MyAppSystemSettings">
<configCache enabled="true" refresh="* 6 * * *" />
<configProvider
assembly="Microsoft.ApplicationBlocks.ConfigurationManagement, Version=1.0.0.0,Culture=neutral,PublicKeyToken=e64cb664730084d3"
type="Microsoft.ApplicationBlocks.ConfigurationManagement.Storage.XmlFileStorage"
signed="false"
refreshOnChange="false"
encrypted="false"
path="C:\Program Files\MyApp\Config\MyAppSystemSettings.Config" />
</configSection>
</applicationConfigurationManagement>
</configuration>
As can be seen this is referencing the MyAppSystemSettings.Config 'sub' config file which looks like:
<configuration>
<MyAppSystemSettings>
<XmlSerializableHashtable xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Entries>
<Entry>
<key xsi:type="xsd:string">Key0</key>
<value xsi:type="xsd:string">Value0</value>
</Entry>
<Entry>
<key xsi:type="xsd:string">Key1</key>
<value xsi:type="xsd:string">Value1</value>
</Entry>
<Entry>
<key xsi:type="xsd:string">ExtraConfigFile</key>
<value xsi:type="xsd:string">C:\Program Files\MyApp\Config\ExtraConfig.xml</value>
</Entry>
</XmlSerializableHashtable>
</MyAppSystemSettings>
</configuration>
Considering that the app.config file refers to 10+ 'sub' config files similar to MyAppSystemSettings.Config and that they each contain 100+ entries I'm looking for the simplest way to migrate them to use System.Configuration correctly to give me the same results as the .net 1.1 solution using CMAB?
Related
I am developing APIs with Service Fabric into a big solution. After I created the services I needed (an Actor, a stateful and a stateless with .NET Framework) and I made a walking skeleton of the APIs.
I started to test and service fabric always threw the error "Service does not exist" (I'm 100% sure that the uri was right) when was the time to call the Actor (same error with both ActorProxyFactory and ActorProxy). I wathced on Cluster Explorer and under my SF App there was only the other two service. But the ActorServiceType was registered.
So I decide to create two simple SF app with an actor and I got the same error and also I don't see them on Cluster explorer.
In no projects I touched the ServiceManifest, ApplicationManifest or whatelse.
Here the versions of the tools I use:
Windows 11 Enterprise
Visual Studio Enterprise v16.11.9 with .Net Framework 4.7.1
Service Fabric Runtime 8.1.321.9590
Serive Fabric SDK 5.1.321.9590
Nuget Microsoft.SerivceFabric 8.1.321
Nuget Microsoft.ServiceFabric.Actors 5.1.321 (For the nuget packages I tried everything)
Microsoft.VisualStudio.Azure.Fabric.MSBuild 1.7.6 (also this I tried
every version)
My auto-generated setting.xml:
<?xml version="1.0" encoding="utf-8"?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Section Name="MyActorServiceReplicatorConfig">
<Parameter Name="ReplicatorEndpoint" Value="MyActorServiceReplicatorEndpoint" />
<Parameter Name="BatchAcknowledgementInterval" Value="0.005" />
</Section>
<Section Name="MyActorServiceReplicatorSecurityConfig">
<Parameter Name="CredentialType" Value="None" />
</Section>
<!-- The content will be generated during build -->
</Settings>
My auto-generated service-manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="MyActorPkg" Version="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<ServiceTypes>
<StatefulServiceType ServiceTypeName="MyActorServiceType" HasPersistedState="true">
<Extensions>
<Extension Name="__GeneratedServiceType__" GeneratedId="5f4d2e71-68d5-43f4-b8a3-60990017b54d|Persisted">
<GeneratedNames xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
<DefaultService Name="MyActorService" />
<ReplicatorEndpoint Name="MyActorServiceReplicatorEndpoint" />
<ReplicatorConfigSection Name="MyActorServiceReplicatorConfig" />
<ReplicatorSecurityConfigSection Name="MyActorServiceReplicatorSecurityConfig" />
<StoreConfigSection Name="MyActorServiceLocalStoreConfig" />
<ServiceEndpointV2_1 Name="MyActorServiceEndpointV2_1" />
</GeneratedNames>
</Extension>
</Extensions>
</StatefulServiceType>
</ServiceTypes>
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>MyActor.exe</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
<ConfigPackage Name="Config" Version="1.0.0" />
<Resources>
<Endpoints>
<Endpoint Name="MyActorServiceEndpointV2_1" />
<Endpoint Name="MyActorServiceReplicatorEndpoint" />
</Endpoints>
</Resources>
<!-- The content will be generated during build -->
</ServiceManifest>
my auto-generated application-manifest:
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="MyActorPkg" Version="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<ServiceTypes>
<StatefulServiceType ServiceTypeName="MyActorServiceType" HasPersistedState="true">
<Extensions>
<Extension Name="__GeneratedServiceType__" GeneratedId="5f4d2e71-68d5-43f4-b8a3-60990017b54d|Persisted">
<GeneratedNames xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
<DefaultService Name="MyActorService" />
<ReplicatorEndpoint Name="MyActorServiceReplicatorEndpoint" />
<ReplicatorConfigSection Name="MyActorServiceReplicatorConfig" />
<ReplicatorSecurityConfigSection Name="MyActorServiceReplicatorSecurityConfig" />
<StoreConfigSection Name="MyActorServiceLocalStoreConfig" />
<ServiceEndpointV2_1 Name="MyActorServiceEndpointV2_1" />
</GeneratedNames>
</Extension>
</Extensions>
</StatefulServiceType>
</ServiceTypes>
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>MyActor.exe</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
<ConfigPackage Name="Config" Version="1.0.0" />
<Resources>
<Endpoints>
<Endpoint Name="MyActorServiceEndpointV2_1" />
<Endpoint Name="MyActorServiceReplicatorEndpoint" />
</Endpoints>
</Resources>
<!-- The content will be generated during build -->
</ServiceManifest>
my local1node.xml file:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/TEST2.MYACTOR.SF" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters />
</Application>
screens cluster explorer:
screen cluster explorer
screen cluster explorer service type
The solution of this problem found on this github issue with a step-by-step guide.
In few words if you have more than installation of Visual Studio (2019 and 2022) a service fabric package cache go in conflict.
I have Web.config:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" requirePermission="false"/>
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
<property name="connection.connection_string">{old_connection}</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="proxyfactory.factory_class">NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate</property>
<property name="show_sql">false</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
</session-factory>
</hibernate-configuration>
</configuration>
I apply a transformation. Web.Release.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"
xmlns:hib="urn:nhibernate-configuration-2.2">
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" requirePermission="false"/>
</configSections>
<hib:hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<hib:session-factory>
<hib:property xdt:Transform="Replace" xdt:Locator="Match(name)" name="connection.connection_string">{new_connection}</hib:property>
</hib:session-factory>
</hib:hibernate-configuration>
</configuration>
Run in VS2012 in Release, the transformation does not occur. The string is not replaced.
In what could be the reason?
The transformation does not happen because the element names differs from your baseline Web.config. If you remove the hib namespace, transformation will take place.
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property xdt:Transform="Replace" xdt:Locator="Match(name)" name="connection.connection_string">{new_connection}</property>
</session-factory>
</hibernate-configuration>
</configuration>
Another thing to note. If your current configuration is Release and you are running your application through Visual Studio, the server will point to the root of your project. In the root, you will have Web.config, Web.Debug.config and Web.Release.config and the server will pick-up the usual configuration file, without the transformation (ie Web.config).
I tried to create a setup file using Bootstrapper which is intended to first run the .NET framework setup file and only then the MyApp.exe. After finishing the project I got the final setup file, but even it doesn't get started after double click or pressing enter after selecting the file. I don't know where I was wrong.
This is program.cs file:
using Microsoft.Tools.WindowsInstallerXml.Bootstrapper;
namespace testingBoot
{
class Program:BootstrapperApplication
{
static void Main(string[] args)
{
Console.WriteLine("This is tesing for the bootStrapper");
Console.Read();
}
protected override void Run()
{
throw new NotImplementedException();
}
}
}
And my WiX installation file is here
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle UpgradeCode="46C265F4-3F60-4781-9EF6-DB889C115D55" Version="1.0.0.0">
<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost" >
<Payload SourceFile="BootstrapperCore.config" />
<Payload SourceFile="C:\Program Files (x86)\WiX Toolset v3.7\SDK\Microsoft.Deployment.WindowsInstaller.dll" />
</BootstrapperApplicationRef>
<Variable Name="LaunchTarget"
Value="[ProgramFiles64Folder]Folder\Exe Name.exe"/>
<Chain>
<PackageGroupRef Id="Netfx4Full"/>
<ExePackage SourceFile="$(var.PATH)\testingBoot.exe"/>
</Chain>
</Bundle>
<Fragment>
<WixVariable Id="WixMbaPrereqPackageId"
Value="Netfx4Full"/>
<WixVariable Id="WixMbaPrereqLicenseUrl"
Value="NetfxLicense.rtf" />
<util:RegistrySearch Root="HKLM"
Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"
Value="Version"
Variable="Netfx4FullVersion" />
<util:RegistrySearch Root="HKLM"
Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"
Value="Version"
Variable="Netfx4x64FullVersion"
Win64="yes" />
<PackageGroup Id="Netfx4Full">
<ExePackage Id="Netfx4Full"
Cache="no"
Compressed="yes"
PerMachine="yes"
Permanent="yes"
Vital="yes"
Name="dotNetFx40_Full_x86_x64.exe"
SourceFile="dotNetFx40_Full_x86_x64.exe"
DetectCondition="VersionNT64" />
</PackageGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents"
Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->
</ComponentGroup>
</Fragment>
</Wix>
And also I have changed assemblyName under host to my own assembly name as testingBoot.exe in configuration file BootstrapperCore.config.
Here is my BootStrapperCore.config file's contents:
<configuration>
<configSections>
<sectionGroup
name="wix.bootstrapper"
type="Microsoft.Tools.WindowsInstallerXml.Bootstrapper.BootstrapperSectionGroup, BootstrapperCore">
<section
name="host"
type="Microsoft.Tools.WindowsInstallerXml.Bootstrapper.HostSection, BootstrapperCore" />
</sectionGroup>
</configSections>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" />
<supportedRuntime version="v2.0.50727" />
</startup>
<wix.bootstrapper>
<host assemblyName="testingBoot" >
<supportedFramework version="v4\Full" />
</host>
</wix.bootstrapper>
</configuration>
It appears that your BootstrapperApplication assembly is missing from the BootstrapperApplicationRef element. I should also note that the Burn engine loads your BA assembly directly. It does not launch it as an executable. Thus, to get your BootstrapperApplication loaded, I think you'll want to to make the following change:
<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost" >
<Payload SourceFile="$(var.PATH)\testingBoot.exe"/>
<Payload SourceFile="BootstrapperCore.config" />
<Payload SourceFile="C:\Program Files (x86)\WiX Toolset v3.7\SDK\Microsoft.Deployment.WindowsInstaller.dll" />
</BootstrapperApplicationRef>
That will add the testingBoot.exe to the BootstrapperApplication and if your BoostrapperCore.config file looks like:
<configuration>
<configSections>
<sectionGroup name="wix.bootstrapper" type="Microsoft.Tools.WindowsInstallerXml.Bootstrapper.BootstrapperSectionGroup, BootstrapperCore">
<section name="host" type="Microsoft.Tools.WindowsInstallerXml.Bootstrapper.HostSection, BootstrapperCore" />
</sectionGroup>
</configSections>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" />
</startup>
<wix.bootstrapper>
<host assemblyName="testingBoot">
<supportedFramework version="v4\Full" />
<supportedFramework version="v4\Client" />
</host>
</wix.bootstrapper>
</configuration>
Then the Burn engine will find an assembly named testingBoot and load that. Again, as noted above, testingBoot will be loaded directly and the Run() method will be called directly. The Main() entry point will be skipped because the Burn engine does not run the assembly as an executable.
I have a console application that loads other libraries (DLL's). I'm using Spring.NET. My console application is very simple, load the app.config that is configured through DI to initialize the chosen library.
Code
ContextRegistry.GetContext();
Configuration (app.config)
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context"
type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects"
type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects"/>
<resource uri="assembly://MyDLL/MyDLL.Config/Services.xml"/>
</context>
<objects xmlns="http://www.springframework.net"
xmlns:aop="http://www.springframework.net/aop">
</objects>
</spring>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup></configuration>
Each library has its own "services.xml" file. These libraries also use Spring.NET.
<objects xmlns="http://www.springframework.net"
xmlns:aop="http://www.springframework.net/aop">
<object id="componentObj"
type="MyDLL.Services.ComponentService, MyDLL"
singleton="true" />
<object
id="componentServiceHost"
type="Spring.ServiceModel.Activation.ServiceHostFactoryObject, Spring.Services">
<property name="TargetName"
value="componentObj" />
</object>
</objects>
Getting a excpetion "Process is terminated due to StackOverflowException." If I comment out the <object id="componentServiceHost", the exception does not occur.
The VS console in debug shows
A first chance exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll
A first chance exception of type 'Spring.Objects.Factory.ObjectCreationException' occurred in Spring.Core.dll
A first chance exception of type 'Spring.Objects.Factory.ObjectCreationException' occurred in Spring.Core.dll
Managed (v4.0.30319)' has exited with code -2147023895 (0x800703e9).
You can also place spring configuration in plain xml files and include those with your library. This way, you can easily share this configuration without the need of sharing an app.config.
You do have to explicitly reference this configuration file in the configuration of your host console application, but that's no duplication. The app.config of your console application host will look like this:
...
<spring>
<context>
<resource uri="file://services.xml"/>
<resource uri="assembly://MyAssembly/MyDataAccess/data-access.xml"/>
</context>
</spring>
See the spring.net docs how to configure a configuration in xml.
I'm trying to add basic authenthication to my webservice. I followed steps from this article and ended up with this in my web.config file:
<configuration>
<httpModules>
<add name="BasicAuthenticationModule"
type="Mono.Http.Modules.BasicAuthenticationModule, Mono.Http, Version=2.0.0.0, PublicKeyToken=0738eb9f132ed756"/>
</httpModules>
<appSettings>
<add key="Authentication" value="Basic" />
<add key="Basic.Users" value="/home/vadmin/Projects/TestService/TestService/users.xml" />
<add key="Basic.Realm" value="My Realm" />
</appSettings>
</configuration>
My users.xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<users>
<user name="adrian" password="adrian">
<role name="user" />
</user>
</users>
When I run xsp2 and then go to
http://localhost:8080/TestService.asmx
user and password prompt appears. But after I enter correct user and password it asks me again and again. I'm pretty sure that path to users.xml file is correct, tried running xsp2 with --verbose options hoping for some error messages with no luck.
Can anyone help me debug this situation?
If you specify a path starting with / in config file, this will be interpreted not as a root directory of your filesystem, but as a root directory of your website - i.e. /home/vadmin/Projects/TestService/TestService.
So the path starting with / should be relative to website root folder - in your case this will be "/users.xml" if users.xml file is in project folder.