I have client endpoints as below in my web.config, we have production server located geographically for e.g. America, Europe, Asia etc and all have their own base uri.
e.g. web.config is as below
<client>
<endpoint address="http://localhost:9000/ServiceA.svc" binding="wsHttpBinding" contract="IServiceA" name="ServiceA"></endpoint>
<endpoint address="http://localhost:9000/ServiceB.svc" binding="wsHttpBinding" contract="IServiceA" name="ServiceB"></endpoint>
<endpoint address="http://localhost:9000/ServiceC.svc" binding="wsHttpBinding" contract="IServiceA" name="ServiceC"></endpoint>
<endpoint address="http://localhost:9000/ServiceD.svc" binding="wsHttpBinding" contract="IServiceA" name="ServiceD"></endpoint>
<endpoint address="http://localhost:9000/ServiceE.svc" binding="wsHttpBinding" contract="IServiceA" name="ServiceE"></endpoint>
For Ameria region I have Web.America.config but it should be transformed as below
<client>
<endpoint xdt:Transform="SetAttributes(address)" xdt:Locator="Match(name)" address="http://localhost:9000/america/ServiceA.svc" name="ServiceA"></endpoint>
<endpoint xdt:Transform="SetAttributes(address)" xdt:Locator="Match(name)" address="http://localhost:9000/america/ServiceB.svc" name="ServiceB"></endpoint>
...
...
But I don't want this duplication as I only need to change base address. Is there any better way of doing this?
Related
I am working on project dotnet framework 4.8.
I want to remove some specific lines from my web.config while copying the file to the artifact using azure pipelines.
Below the CopyFiles task:
`- task: CopyFiles#2
displayName: Copy web config into the Package
condition: eq(variables.generateConfigs, true)
inputs:
SourceFolder: '$(ReleasesPath.SourceFolderName)'
Contents: |
Web.config
TargetFolder: '$(CopyPath.TragetFolderName)'
CleanTargetFolder: false
preserveTimestamp: true`
Content of my Web.config :
`<service behaviorConfiguration="mybehavior" name="">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="" contract=""/>
<!--<endpoint address="mex" binding="mexTcpBinding" contract="Contract1"/>-->
</service>
<service behaviorConfiguration="mybehavior" name="">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="" contract=""/>
<!--<endpoint address="mex" binding="mexTcpBinding" contract="Contract2"/>-->
</service>`
The Goal:
Remove all lines with comments.
Expected:
`<service behaviorConfiguration="mybehavior" name="">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="" contract=""/>
</service>
<service behaviorConfiguration="mybehavior" name="">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="" contract=""/>
</service>`
I doubt if there are built-in tools for this. But you can run PowerShell script to do this for you before you copy file.
- powershell: |
$path = "web.config"
Get-Content $path | Where-Object { $_ -notmatch "^\s*<!--" } | Set-Content $path
I'm trying to develop a service with WCF but I can't find the certificate that I created, this certificate is located under TrustedPeple folder. So far this is my chunk of code that I wrote:
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
StoreLocation.CurrentUser,
StoreName.My,
X509FindType.FindBySubjectName,
"WCfClient");
As you can see from the above code, I also tried to manually set the certificate characteristics but I still can't find it.
Also I'll post a portion of my conif xml file for a better understanding:
<services>
<service
name="XMLServices.CriDecServices.CriDecService"
behaviorConfiguration="wsHttpCertificateBehavior">
<endpoint name="CriDecPoint"
address=""
binding="wsHttpBinding"
bindingConfiguration="wsHttpEndpointBinding"
contract="XMLContracts.ServiceContracts.ICriDecService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/XMLServices/CriDecServices/CriDecService" />
</baseAddresses>
</host>
</service>
<service
name="XMLServices.UtenteServices.UtenteService"
behaviorConfiguration="wsHttpCertificateBehavior">
<endpoint
name="UserPoint"
address=""
binding="wsHttpBinding"
bindingConfiguration="wsHttpEndpointBinding"
contract="XMLContracts.ServiceContracts.IUtenteService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8766/XMLServices/UtenteServices/UtenteService" />
</baseAddresses>
</host>
</service>
</services>
This is the exception that I get:
"Client certificate not given. Specify a client certificate in ClientCredentials."
Can anyone help me out to understand why I can't seem to find my certificate? Thanks
If you look here you'll see that the store you are trying to use isn't the one from the trusted people folder but the one from the personal folder
you should use
StoreName.TrustedPeople
look here for more details https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.storename(v=vs.110).asp
also most likely you need StoreLocation.LocalMachine.
For a IIS hosted service I have to get the full address of the local machine.
In the Web.config that value is perfectly configured
<services>
<service name="MyService.Service.MyService">
<endpoint address="" behaviorConfiguration="MexFlatWsdlBehavior"
binding="basicHttpBinding" bindingConfiguration="secureHttpBinding"
name="TpsNotification" bindingNamespace="http://org.com/MyService/2014/11"
contract="MyService.Service.ISomeEndpoint">
<identity>
<dns value="THESERVER.myorg.net" />
</identity>
</endpoint>
<endpoint address="" behaviorConfiguration="MexFlatWsdlBehavior"
binding="basicHttpBinding" bindingConfiguration="secureHttpBinding"
name="TpsPluginFramework" bindingNamespace="http://org.com/MyService/2014/11"
contract="MyService.Service.IOtherEndpoint">
<identity>
<dns value="THESERVER.myorg.net" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="https://THESERVER.myorg.net:443/MyService.svc" />
</baseAddresses>
</host>
</service>
</services>
Any of dns value or baseAddress would be perfectly fine.
But I see no way to get to that value from IIS.
I tried ConfigurationManager and WebConfiguration and HostingEnvironment.
Furthermore I tried
var hostName = System.Net.Dns.GetHostName();
which works for some cases, but not for this server, because the configured address is not the primary dns address, which is returned here.
Any options?
Try loading the config file in to a linq to xml doc, then you can query it all you want ...
var config = XDocument.Load("Web.Config");
var baseAddress = config.Elements("baseAddresses")
.Elements()
.First()
.Attribute("baseAddress")
.Value;
If all else fails, use the brute force approach :)
Another option might be ...
Since you are in the context of a request to a server why not use the request object ...
var host = Request.Url.Host;
That was simpler!
Mine is windows application. I am using web service. When i add service reference to my application it is generated one app.config file.
<client>
<endpoint address="http://58.71.131.223/uucpapi/UUCPAPIServer.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IUUCPAPIServer"
contract="UUCPAPI.IUUCPAPIServer" name="WSHttpBinding_IUUCPAPIServer">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
and i am calling this API as
UUCPAPI.UUCPAPIServerClient uucp = new UUCPAPI.UUCPAPIServerClient();
here it is throwing exception as
Could not find default endpoint element that references contract
'UUCPAPI.IUUCPAPIServer' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element."
<client>
<endpoint address="http://...../uucpapi/UUCPAPIServer.svc"
binding="wsHttpBinding"
binding configuration="WSHttpBinding_IUUCPAPIServer"
contract="UUCPAPI.IUUCPAPIServer"
name="WSHttpBinding_IUUCPAPIServer">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
In the following config file excerpt, the WCF service has two endpoints.
<service behaviorConfiguration="AtomTcpHub.Behavior"
name="AtomTcpHub.HubTcp">
<endpoint address="" binding="netTcpBinding"
name="AtomHubEndpoint" contract="AtomLib.IAtomPublisher">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
name="" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/AtomTcpHub/" />
<add baseAddress="net.tcp://dv-pw/AtomTcpHub/" />
</baseAddresses>
</host>
</service>
In my code there is discovery logic, which responds to a UDP request by replying with the connection Uri for the WCF service. Obtaining a collection of endpoints is straightforward.
System.Configuration.Configuration config = System.Configuration
.ConfigurationManager
.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None);
ServicesSection section = config.SectionGroups["system.serviceModel"]
.Sections["services"] as ServicesSection;
ServiceEndpointElementCollection seec =
section.Services["AtomTcpHub.HubTcp"].Endpoints;
The problem is extracting the ServiceEndpointElement. We can have it by index:
ServiceEndpointElement see = seec[0];
but this is brittle; if the order of nodes changes it will break. Visual Studio tells me there is another indexer permitting an object value, but there is no further indication. Experimentation tells me that it isn't the value of the name attribute.
The following code works, but it's just hideous.
string serviceEndpointUri;
foreach(ServiceEndpointElement serviceEndpointElement in seec)
if (serviceEndpointElement.Name == "AtomHubEndpoint")
{
_serviceEndpointUri = serviceEndpointElement.Address.AbsoluteUri;
break;
}
Is there a more direct or more elegant way to do this?
You could always use some Linq to accomplish this, to simply shorten things a bit.
ServiceEndpointElement element =
seec.OfType<ServiceEndpointElement>()
.FirstOrDefault(s => s.Name == "AtomHubEndpoint");