Web.config transformation and search and replace - web-config

I need to switch out an IP address in multiple WCF services in web.config. With web.config transformation, is there any way, besides specifying each an every address by xpath, to create a search and replace statement. E.g. switch out IP address 1.2.3.4 with 4.3.2.1 for all instances of 1.2.3.4

Say your Web.config is something like this (a simplified scenario, but // in XPath works everywhere):
<configuration>
<endpoint address="1.2.3.4" />
<endpoint address="1.2.3.4" />
<endpoint address="1.2.3.4" />
<endpoint address="1.2.3.4" />
</configuration>
then you will need something like this:
<?xml version="1.0"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<replaceAll>
<endpontAddresses xdt:Locator="XPath(//endpoint[#address='1.2.3.4'])" xdt:Transform="SetAttributes(address)" address="4.3.2.1" />
</replaceAll>
</configuration>
NOTE: this XPath will look for every element in the whole Web.config and check whether given element has address attribute with value equal to "1.2.3.4".
If you need something more general then try this:
<?xml version="1.0"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<replaceAll>
<endpontAddresses xdt:Locator="XPath(//*[#address='1.2.3.4'])" xdt:Transform="SetAttributes(address)" address="4.3.2.1" />
</replaceAll>
</configuration>
This will look at every XML element (due to the asterisk: *) and check whether it has address attribute with value equal to "1.2.3.4".
So this will work for a file like this:
<configuration>
<endpoint name="serviceA" address="1.2.3.4" />
<endpoint name="serviceB" address="1.2.3.4" />
<endpoint name="serviceC" address="1.2.3.4" />
<endpoint2 address="1.2.3.4" />
<endpoint3 address="1.2.3.4" />
<endpoint4 address="1.2.3.4" />
<innerSection>
<endpoint address="1.2.3.4" />
<anotherEndpoint address="1.2.3.4" />
<sampleXmlElement address="1.2.3.4" />
</innerSection>
</configuration>
Now if you want to limit substitutions to a certain section i.e. <system.serviceModel> then you can use an XPath like this:
<endpontAddresses xdt:Locator="XPath(/configuration/system.serviceModel//*[#address='1.2.3.4'])" xdt:Transform="SetAttributes(address)" address="4.3.2.1" />
This will update addresses only in <system.serviceModel> section
<configuration>
<endpoint name="serviceA" address="1.2.3.4" />
<endpoint name="serviceB" address="1.2.3.4" />
<endpoint name="serviceC" address="1.2.3.4" />
<endpoint2 address="1.2.3.4" />
<endpoint3 address="1.2.3.4" />
<endpoint4 address="1.2.3.4" />
<innerSection>
<endpoint address="1.2.3.4" />
<anotherEndpoint address="1.2.3.4" />
<sampleXmlElement address="1.2.3.4" />
</innerSection>
<system.serviceModel>
<endpoint name="serviceB" address="1.2.3.4" />
<endpoint name="serviceC" address="1.2.3.4" />
<endpoint2 address="1.2.3.4" />
<innerSection>
<endpoint address="1.2.3.4" />
<anotherEndpoint address="1.2.3.4" />
<sampleXmlElement address="1.2.3.4" />
</innerSection>
</system.serviceModel>
</configuration>
Give those a try and choose the one that suits your needs most.
NOTE: This has a limitation that you need to specify what is the name of the attribute that contains the IP (1.2.3.4) but I think its better to be explicit rather than have magic happen here. If you have many attibute names just repeat the

Related

Bad Request REST/SOAP for a WCF Webservice

A WCF service needs to be capable to SOAP and REST format.
It returns Bad Request (400), below is my web config file:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ILoginSVC" allowCookies="true" maxBufferPoolSize="20000000" maxBufferSize="70000000" maxReceivedMessageSize="70000000">
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="webHttpBindingILoginSVC" allowCookies="true" maxBufferSize="100000000" maxBufferPoolSize="100000000" maxReceivedMessageSize="100000000" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<services>
<service name="LoginSVC.LoginSVC">
<host>
<baseAddresses>
<add baseAddress="http://localhost:59900/LoginSVC" />
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="LoginSVC.ILoginSVC">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="REST" binding="webHttpBinding" contract="LoginSVC.ILoginSVC" behaviorConfiguration="RESTEndPointBehaviour">
</endpoint>
</service>
</services>
</system.serviceModel>
In your configuration file, you have not assigned the binding configuration you created, so use the default BasicHttpBinding. You need to explicitly assign the binding you defined (BasicHttpBinding_ILoginSVC) to your endpoint like this:
<endpoint address="" bindingConfiguration="BasicHttpBinding_ILoginSVC" binding="basicHttpBinding" contract="LoginSVC.ILoginSVC" />

Service Fabric Explorer Health State Unknown

The node in my partition keeps switching between Health State = OK and Health State = unknown.
Sometimes the node disappears.
I have tried deleting the service, the app and unprovisioning the type, then redeploying, however I get the same problem.
It is a Service Fabric stateful service, and it's running fine locally, the issue I'm having is only in my dev environment.
I'm using 5 nodes.
ServiceManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Integration.Optical.ServicePkg"
Version="1.0.0"
xmlns="http://schemas.microsoft.com/2011/01/fabric"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceTypes>
<!-- This is the name of your ServiceType.
This name must match the string used in the RegisterServiceAsync call in Program.cs. -->
<StatefulServiceType ServiceTypeName="Integration.Optical.ServiceType" />
</ServiceTypes>
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>Integration.Optical.Service.exe</Program>
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</EntryPoint>
<EnvironmentVariables>
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value=""/>
<EnvironmentVariable Name="KEYVAULT_ENDPOINT" Value=""/>
</EnvironmentVariables>
</CodePackage>
<!-- Config package is the contents of the Config directoy under PackageRoot that contains an
independently-updateable and versioned set of custom configuration settings for your service. -->
<ConfigPackage Name="Config" Version="1.0.0" />
<Resources>
<Endpoints>
<!-- This endpoint is used by the communication listener to obtain the port on which to
listen. Please note that if your service is partitioned, this port is shared with
replicas of different partitions that are placed in your code. -->
<Endpoint Name="ServiceEndpoint" />
<!-- This endpoint is used by the replicator for replicating the state of your service.
This endpoint is configured through a ReplicatorSettings config section in the Settings.xml
file under the ConfigPackage. -->
<Endpoint Name="ReplicatorEndpoint" />
</Endpoints>
</Resources>
</ServiceManifest>
ApplicationManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="Integration.OpticalType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Integration.Optical.Service_ASPNETCORE_ENVIRONMENT" DefaultValue="" />
<Parameter Name="Integration.Optical.Service_KEYVAULT_ENDPOINT" DefaultValue="" />
<Parameter Name="Integration.Optical.Service_MinReplicaSetSize" DefaultValue="3" />
<Parameter Name="Integration.Optical.Service_PartitionCount" DefaultValue="1" />
<Parameter Name="Integration.Optical.Service_TargetReplicaSetSize" DefaultValue="3" />
</Parameters>
<!-- Import the ServiceManifest from the ServicePackage. The ServiceManifestName and ServiceManifestVersion
should match the Name and Version attributes of the ServiceManifest element defined in the
ServiceManifest.xml file. -->
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Integration.Optical.ServicePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<EnvironmentOverrides CodePackageRef="code">
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="[Integration.Optical.Service_ASPNETCORE_ENVIRONMENT]" />
<EnvironmentVariable Name="KEYVAULT_ENDPOINT" Value="[Integration.Optical.Service_KEYVAULT_ENDPOINT]" />
</EnvironmentOverrides>
</ServiceManifestImport>
<DefaultServices>
<!-- The section below creates instances of service types, when an instance of this
application type is created. You can also create one or more instances of service type using the
ServiceFabric PowerShell module.
The attribute ServiceTypeName below must match the name defined in the imported ServiceManifest.xml file. -->
<Service Name="Integration.Optical.Service" ServicePackageActivationMode="ExclusiveProcess">
<StatefulService ServiceTypeName="Integration.Optical.ServiceType" TargetReplicaSetSize="[Integration.Optical.Service_TargetReplicaSetSize]" MinReplicaSetSize="[Integration.Optical.Service_MinReplicaSetSize]">
<UniformInt64Partition PartitionCount="[Integration.Optical.Service_PartitionCount]" LowKey="-9223372036854775808" HighKey="9223372036854775807" />
</StatefulService>
</Service>
</DefaultServices>
</ApplicationManifest>
ApplicationParameters/Cloud.xml:
<?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:/Integration.Optical" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Integration.Optical.Service_ASPNETCORE_ENVIRONMENT" Value="" />
<Parameter Name="Integration.Optical.Service_KEYVAULT_ENDPOINT" Value="" />
<Parameter Name="Integration.Optical.Service_PartitionCount" Value="1" />
<Parameter Name="Integration.Optical.Service_MinReplicaSetSize" Value="1" />
<Parameter Name="Integration.Optical.Service_TargetReplicaSetSize" Value="1" />
</Parameters>
</Application>
Not sure what part of this fixed it. But this is what I did and it's now working:
In ServiceManifest.xml I added HasPersistedState = true:
<StatefulServiceType ServiceTypeName="Integration.Optical.ServiceType" HasPersistedState="true" />
I moved the app configuration code
ServiceRuntime.RegisterServiceAsync...
from Service.RunAsync() to Program.Main()

REST Service WebHttpBinding with Http and Https

I have a REST service. This service need to be work with http and https.
I've tried to add two endpoint in my web.config file. But i get this error when i try to browse my service over http:
Could not find a base address that matches scheme https for the
endpoint with binding WebHttpBinding. Registered base address schemes
are [http].
and i get this error when i try to browse over https:
Could not find a base address that matches scheme http for the endpoint with binding WebHttpBinding. Registered base address schemes are [https].
If i remove one of endpoint from my config file, the both http and https services works fine.
I checked this link: WebHttpBinding with Http and Https
But when i remove endpoints from my config file, the both http and https services runs without any errors on web browser. But when i try to call one of my methods (over a rest client tool) in this service it gets:
500 Internal Server Error.
How can i run this service over http and https without any errors?
My config file is like this:
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding" bindingConfiguration="webHttpBinding"/>
<add scheme="https" binding="webHttpBinding" bindingConfiguration="webHttpsBinding"/>
</protocolMapping>
<bindings>
<webHttpBinding>
<binding name="webHttpBinding">
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
<binding name="webHttpsBinding">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="MyProject.MyService" behaviorConfiguration="serviceBehavior">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="web" bindingConfiguration="webHttpBinding" contract="MyProject.IMyService" />
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="web" bindingConfiguration="webHttpsBinding" contract="MyProject.IMyService" />
<!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />-->
<!--<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>-->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization serviceAuthorizationManagerType="MyProject.RestAuthorizationManager, MyProject"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
here is a sample web.config in order to have both http and https support. i hope solve your problem:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="SoapBinding" />
</basicHttpBinding>
<basicHttpsBinding>
<binding name="SecureSoapBinding" />
</basicHttpsBinding>
<webHttpBinding>
<binding name="RestBinding" />
<binding name="SecureRestBinding">
<security mode="Transport" />
</binding>
</webHttpBinding>
<mexHttpBinding>
<binding name="MexBinding" />
</mexHttpBinding>
<mexHttpsBinding>
<binding name="SecureMexBinding" />
</mexHttpsBinding>
</bindings>
<client />
<services>
<service behaviorConfiguration="ServiceBehavior" name="Interface.Core">
<endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="SoapBinding" name="Soap" contract="Interface.ICore" />
<endpoint address="soap" binding="basicHttpsBinding" bindingConfiguration="SecureSoapBinding" name="SecureSoap" contract="Interface.ICore" />
<endpoint address="" behaviorConfiguration="Web" binding="webHttpBinding" bindingConfiguration="RestBinding" name="Rest" contract="Interface.ICore" />
<endpoint address="" behaviorConfiguration="Web" binding="webHttpBinding" bindingConfiguration="SecureRestBinding" name="SecureRest" contract="Interface.ICore" />
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="MexBinding" name="Mex" contract="IMetadataExchange" />
<endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="SecureMexBinding" name="SecureMex" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="Web">
<webHttp helpEnabled="true" defaultBodyStyle="Bare" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="false" />
</system.webServer>
</configuration>

Nlog with MongoDB connection and target

I am trying to use a logger that will log into MongoDB, but I can not get it to work. In the same configuration i have set up the loggers to log using an email and file and both work just fine.
Here is my NLog.config file
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
<add assembly="NLog.MongoDB"/>
</extensions>
<!--
See http://nlog-project.org/wiki/Configuration_file
for information on customizing logging rules and outputs.
-->
<targets>
<target xsi:type="File" name="file" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
<target xsi:type="Mongo"
name="mongoDefault"
connectionString="mongodb://localhost/nlog"
collectionName="cdss"
cappedCollectionSize="26214400">
<property name="ThreadID" layout="${threadid}" bsonType="Int32" />
<property name="ThreadName" layout="${threadname}" />
<property name="ProcessID" layout="${processid}" bsonType="Int32" />
<property name="ProcessName" layout="${processname:fullName=true}" />
<property name="UserName" layout="${windows-identity}" />
</target>
<target name="TcpOutlet" xsi:type="Chainsaw" address="tcp4://localhost:4505" > </target>
<target name="Email" xsi:type="Mail"
smtpServer="localhost"
smtpPort="25"
smtpAuthentication="None"
enableSsl="false"
from="ssss#sdsdfs"
to="ssss#sdsdfs" html="true"
/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="file,TcpOutlet,mongoDefault,Email" />
<logger name="*" minlevel="Error" writeTo="file,TcpOutlet,Email,mongoDefault" />
</rules>
</nlog>
I have installed the Nlog.Mongo nugget also. My database is called nlog. Whatever i do, the loggers do not write in the mongodb. I am using NLogger.

Web.config transformation: how to apply a transformation to all node matching a Locator expression?

I've recently discovered the web.config automatic transformation in the web deploy tool of visual studio 2010.
It's working well, but I have a scenario I can't seem to get working.
Assume I have the following root Web.config
<services>
<service name="Service1">
<endpoint address="" binding="customBinding" bindingConfiguration="LargeBufferBinding"
contract="Service1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service name="Service2">
<endpoint address="" binding="customBinding" bindingConfiguration="LargeBufferBinding"
contract="Service2" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service name="Service3">
<endpoint address="" binding="customBinding" bindingConfiguration="LargeBufferBinding"
contract="Service3" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
For my Web.Release.config, I want all the endpoint nodes with a binding of mexHttpBinding to be removed.
I've used the following in my Web.Release.config:
<services>
<service>
<endpoint binding="mexHttpBinding" xdt:Locator="Match(binding)" xdt:Transform="Remove" />
</service>
</services>
However, this will only remove the first match, in the Service1, but not the following ones.
I've tried various way of locating the node, on the endpoint and service node, but only the first match ever gets replaced.
Is there a way to get all the <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> to be removed ?
Thanks.
I've just tried this and using RemoveAll instead of Remove seems to do the trick:
<services>
<service>
<endpoint binding="mexHttpBinding" xdt:Locator="Match(binding)" xdt:Transform="RemoveAll" />
</service>
</services>