Endpoint and WSHttpBinding programmatically - c#

I'm trying to move the endpoint and wshttpbinding configuration to a c# file so I can change the endpoint address at runtime (select from dropdown, process etc). However after creating a WsHttpBinding object, EndpointAddress object and passing them to my client. It will throw the following exception:
System.ServiceModel.FaultException: The caller was not authenticated
by the service
This is the same exception I get if the user credentials are incorrect. However they haven't changed from using the Web.config file to creating these config options programmatically.
Web.config (works):
<binding name="myService" maxReceivedMessageSize="2147483647">
<readerQuotas
maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>
</binding>
<client>
<endpoint
address="https://address/myservice.svc"
binding="wsHttpBinding"
bindingConfiguration="myService"
contract="MyService.IMyService"
name="myService"
/>
</client>
MyService service = new MyService();
service.username = "user";
service.password = "pass";
//Success
Programmatically (does not work):
WSHttpBinding wsHttp = new WSHttpBinding();
wsHttp.MaxReceivedMessageSize = 2147483647;
wsHttp.ReaderQuotas.MaxDepth = 2147483647;
wsHttp.ReaderQuotas.MaxStringContentLength = 2147483647;
wsHttp.ReaderQuotas.MaxArrayLength = 2147483647;
wsHttp.ReaderQuotas.MaxBytesPerRead = 2147483647;
wsHttp.ReaderQuotas.MaxNameTableCharCount = 2147483647;
wsHttp.Security.Mode = SecurityMode.TransportWithMessageCredential;
wsHttp.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
wsHttp.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
wsHttp.Security.Message.EstablishSecurityContext = false;
EndpointAddress endpoint = new EndpointAddress("https://address/myservice.svc");
MyService service = new MyService(wsHttp, endpoint);
service.username = "user";
service.password = "pass";
//System.ServiceModel.FaultException: The caller was not authenticated by the service
I've tried following tutorials / looking at answers but I can't figure it out.

My solution
Keep the binding the same.
Change the endpoint so there is no address
<client>
<endpoint
binding="wsHttpBinding" bindingConfiguration="myService"
contract="MyService.IMyService" name="myService" />
</client>
Change endpoint at run time by changing the Uri object and pass the endpoint name your service as the first argument
Uri uri = new Uri("https://address/myservice.svc");
var address = new EndpointAddress(uri);
service= new MyService("myService", address);
service.username = "user";
service.password = "pass";

You can remove EVERYTHING in your app.config - so there is no binding or interface info.
Your runtime code is this:
//create an endpoint address
var address = new EndpointAddress("http://localhost:51353/EmployeeService.svc");
//create a WSHttpBinding
WSHttpBinding binding = new WSHttpBinding();
//create a channel factory from the Interface with binding and address
var channelFactory = new ChannelFactory<IEmployeeService>(binding, address);
//create a channel
IEmployeeService channel = channelFactory.CreateChannel();
//Call the service method on the channel
DataSet dataSet = channel.SelectEmployees();
Just for reference, here is my app.config:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
/************ You can dumb this down to this: ********************************/
var factory = new ChannelFactory<IEmployeeService>(new WSHttpBinding());
var channel = factory.CreateChannel(new EndpointAddress("http://localhost:51353/EmployeeService.svc"));

Related

C# NetTcpBinding Client bindings from other config file

I have a client which is a windows application called Windows.exe. I have a C# class library called ServiceFacade.dll and it has a config file called ServiceFacade.dll.config. In ServiceFacade.dll.config, I have client side bindings like below
<system.serviceModel>
<client>
<endpoint address="net.tcp://localhost:5000/MyService"
binding="netTcpBinding"
contract="IMyService"
name="NetTcpBinding_MyService"/>
</client>
</system.serviceModel>
In ServiceFacade.dll, I have code like below to create proxy
NetTcpBinding binding = new NetTcpBinding("NetTcpBinding_MyService");
ChannelFactory<IMyService> chn = new ChannelFactory<IMyService>(binding);
IMyService service = chn.CreateChannel();
Windows.exe calls ServiceFacade.dll to make service calls.
But below line is looking for NetTcpBinding_MyService in Windows.exe.config instead of ServiceFacade.dll.config
How to make below line to see NetTcpBinding_MyService in ServiceFacade.dll.config but not Windows.exe.config ?
NetTcpBinding binding = new NetTcpBinding("NetTcpBinding_MyService");
You definitely can copy the configuration to the ServiceFacade.dll.config from the Windows.exe.config. I would rather create a service endpoint manually than to copy the configuration when I call the service by using ChannelFactory.
Client-side.
class Program
{
static void Main(string[] args)
{
Uri uri = new Uri("https://vabqia969vm:21011/");
NetTcpBinding binding = new NetTcpBinding();
binding.OpenTimeout = new TimeSpan(0, 10, 0);
binding.MaxReceivedMessageSize = 2147483647;
binding.ReaderQuotas.MaxStringContentLength = 2147483647;
ChannelFactory<ITestService> factory = new ChannelFactory<ITestService>(binding, new EndpointAddress(uri));
ITestService service = factory.CreateChannel();
var result1 = service.GetData(34);
Console.WriteLine(result1);
}
}
//The service contract is shared between the client-side and the server-side.
[ServiceContract]
public interface ITestService
{
[OperationContract]
string GetData(int id);
}
Wish it is useful to you.
I did like below.
I added below in ServiceFacade.dll.config
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="netTcpBindingConfiguration"
closeTimeout="00:10:00"
openTimeout="00:10:00"
receiveTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:5000/MyService"
binding="netTcpBinding"
contract="IMyService"
name="NetTcpBinding_MYService"
bindingConfiguration="netTcpBindingConfiguration" />
</client>
</system.serviceModel>
In ServiceFacade.dll, I have code like below to create proxy
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
Configuration config = ConfigurationManager.OpenExeConfiguration(path);
ConfigurationChannelFactory<IMyService> chn =
new ConfigurationChannelFactory<IMyService>(
"NetTcpBinding_MyService",
config,
new EndpointAddress("net.tcp://localhost:5000/MyService"));
IMyService iMyService = chn.CreateChannel();

Protocol exception error

I'm trying to call soap service in script task but getting this following error. I've added a serviceReference through wsdl url. I don't have idea about what this error is referring to. However i'm able to get the data in SOAPUI
"The header 'ReliableMessaging' from the namespace 'http://sap.com/xi/XI/Message/30' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding."
below is the code i'm using
EndpointAddress endPointAddress = new EndpointAddress("https://sapnxcci.intel.com:8220/XISOAPAdapter/MessageServlet?senderParty=&senderService=MC4510&receiverParty=&receiverService=&interface=Segments&interfaceNamespace=http://intel.com/xi/Intel-MDM/Project/Segment");
SegmentsClient client = new SegmentsClient(BindingUtility.GetInitiativesBinding(), endPointAddress);
client.ClientCredentials.UserName.UserName = "sys_idwcons";
client.ClientCredentials.UserName.Password = "abdc";
SegmentResponse results = client.ListSegments(new SegmentRequest() { SegmentName = "" });
In GetInitiativesBinding contains the following.
public static BasicHttpBinding GetInitiativesBinding()
{
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.MaxReceivedMessageSize = 2147483647;
binding.MaxBufferSize = 2147483647;
binding.ReceiveTimeout = TimeSpan.FromMinutes(5);
binding.SendTimeout = TimeSpan.FromMinutes(5);
return binding;
}
and my App.Config file looks like this
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="SegmentsBinding" />
<binding name="SegmentsBinding1">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://sapnxcci.intel.com:8420/XISOAPAdapter/MessageServlet?senderParty=&senderService=MC4510&receiverParty=&receiverService=&interface=Segments&interfaceNamespace=http%3A%2F%2Fintel.com%2Fxi%2FIntel-MDM%2FProject%2FSegment"
binding="basicHttpBinding" bindingConfiguration="SegmentsBinding"
contract="ServiceReference1.Segments" name="HTTP_Port" />
<endpoint address="https://sapnxcci.intel.com:8220/XISOAPAdapter/MessageServlet?senderParty=&senderService=MC4510&receiverParty=&receiverService=&interface=Segments&interfaceNamespace=http%3A%2F%2Fintel.com%2Fxi%2FIntel-MDM%2FProject%2FSegment"
binding="basicHttpBinding" bindingConfiguration="SegmentsBinding1"
contract="ServiceReference1.Segments" name="HTTPS_Port" />
</client>
</system.serviceModel>
</configuration>
I think it's because the return message from PI contains the tags.
tags are only useful when you have a PI - PI connection.
Reference: https://archive.sap.com/discussions/thread/1839924

WCF Dynamic Binding - How to specify end points?

I'm trying to bind my WCF client using code instead of app.config as I'll need to change host IP addresses for different deployment.
This is my app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICX" maxReceivedMessageSize="1073741824" >
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://127.0.0.1/CX/CX.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICX" contract="CXService.ICX" name="WSHttpBinding_ICX">
<identity>
<servicePrincipalName value="host/SilverStar" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
and this is my code:
public static void StartUp()
{
XmlDictionaryReaderQuotas quota = new XmlDictionaryReaderQuotas();
quota.MaxArrayLength = 2147483647;
quota.MaxBytesPerRead = 2147483647;
quota.MaxDepth = 2147483647;
quota.MaxNameTableCharCount = 2147483647;
quota.MaxStringContentLength = 2147483647;
EndpointAddress addr = new EndpointAddress(new Uri("http://127.0.0.1/CX/CX.svc"));
WSHttpBinding binding1 = new WSHttpBinding();
binding1.Name = "WSHttpBinding_ICX";
binding1.MaxReceivedMessageSize = 1073741824;
binding1.ReaderQuotas = quota;
// Globals.CXClient is the client object
Globals.CXClient = new CXService.CXClient(binding1, addr);
// This line does not compile! Endpoint is read-only!!
Globals.CXClient.Endpoint = new ServiceEndpoint(new ContractDescription("CXService.ICX"), (Binding)binding1, addr);
}
The last line of the code does not compile as .EndPoint is read-only property.
Please help.
try this:
Globals.CXClient.Endpoint.Address = new System.ServiceModel.EndpointAddress("your url here");
This is how I did it.
Globals.CXClient.Endpoint.Contract = new ContractDescription("CXService.ICX");
Globals.CXClient.Endpoint.Binding = binding1;
Globals.CXClient.Endpoint.Address = addr;
However, I encountered another problem. I tried to replace the part:
<identity>
<servicePrincipalName value="host/SilverStar" />
</identity>
by using the following code:
addr.Identity = new SpnEndpointIdentity("host/SilverStar");
This one again fails to compile because addr.Identity is read-only.
I also tried this:
EndpointAddress addr = new EndpointAddress(new Uri("http://127.0.0.1/CX/CX.svc"), new SpnEndpointIdentity("host/SilverStar"), ???);
but the last parameter is an AddressHeaderCollection and I have no idea what should be placed in there.
Please help again. Thanks.

Dynamic config Service Reference C# [duplicate]

I have my first WCF example working. I have the host on a website which have many bindings. Because of this, I have added this to my web.config.
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
This is my default binding http://id.web, which works with the following code.
EchoServiceClient client = new EchoServiceClient();
litResponse.Text = client.SendEcho("Hello World");
client.Close();
I am now trying to set the endpoint address at runtime. Even though it is the same address of the above code.
EchoServiceClient client = new EchoServiceClient();
client.Endpoint.Address = new EndpointAddress("http://id.web/Services/EchoService.svc");
litResponse.Text = client.SendEcho("Hello World");
client.Close();
The error I get is:
The request for security token could not be satisfied because authentication failed.
Please suggest how I may change the endpoint address at runtime?
Additional here is my client config, requested by Ladislav Mrnka
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IEchoService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://id.web/Services/EchoService.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IEchoService" contract="IEchoService"
name="WSHttpBinding_IEchoService">
<identity>
<servicePrincipalName value="host/mikev-ws" />
</identity>
</endpoint>
</client>
</system.serviceModel>
So your endpoint address defined in your first example is incomplete. You must also define endpoint identity as shown in client configuration. In code you can try this:
EndpointIdentity spn = EndpointIdentity.CreateSpnIdentity("host/mikev-ws");
var address = new EndpointAddress("http://id.web/Services/EchoService.svc", spn);
var client = new EchoServiceClient(address);
litResponse.Text = client.SendEcho("Hello World");
client.Close();
Actual working final version by valamas
EndpointIdentity spn = EndpointIdentity.CreateSpnIdentity("host/mikev-ws");
Uri uri = new Uri("http://id.web/Services/EchoService.svc");
var address = new EndpointAddress(uri, spn);
var client = new EchoServiceClient("WSHttpBinding_IEchoService", address);
client.SendEcho("Hello World");
client.Close();
This is a simple example of what I used for a recent test.
You need to make sure that your security settings are the same on the server and client.
var myBinding = new BasicHttpBinding();
myBinding.Security.Mode = BasicHttpSecurityMode.None;
var myEndpointAddress = new EndpointAddress("http://servername:8732/TestService/");
client = new ClientTest(myBinding, myEndpointAddress);
client.someCall();
app.config
<client>
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="LisansSoap"
contract="Lisans.LisansSoap"
name="LisansSoap" />
</client>
program
Lisans.LisansSoapClient test = new LisansSoapClient("LisansSoap",
"http://webservis.uzmanevi.com/Lisans/Lisans.asmx");
MessageBox.Show(test.LisansKontrol("","",""));
We store our URLs in a database and load them at runtime.
public class ServiceClientFactory<TChannel> : ClientBase<TChannel> where TChannel : class
{
public TChannel Create(string url)
{
this.Endpoint.Address = new EndpointAddress(new Uri(url));
return this.Channel;
}
}
Implementation
var client = new ServiceClientFactory<yourServiceChannelInterface>().Create(newUrl);

Authenticating with OpenEMM Web services 2.0

Has anyone got any experience with working with the OpenEMM web services?
When ever I connect to the services I get the following error:
com.sun.xml.wss.XWSSecurityException: Receiver Requirement for Digested Password has not been met; nested exception is com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Receiver Requirement for Digested Password has not been met
Here is my web.config file:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="openemmSoap11">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Digest" />
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://newsletter.********.co.uk/openemm-ws2/" binding="basicHttpBinding"
bindingConfiguration="openemmSoap11" contract="emmservice.openemm"
name="openemmSoap11" />
</client>
</system.serviceModel>
(I had great fun installing an ssl certificate on apache)
Here is my implementation:
var param = new[]
{
new MapItem {key = "email", value = "*******************"},
new MapItem {key = "mailtype", value = "0"}, new MapItem {key = "gender", value = "0"}
};
var service = new AddSubscriberRequest
{
parameters = param,
overwrite = false,
doubleCheck = true,
keyColumn = "email"
};
var request = new openemmClient();
request.ClientCredentials.UserName.UserName = "***********";
request.ClientCredentials.UserName.Password = "********";
request.Open();
request.AddSubscriber(service);
request.Close();
Any ideas where I could be going wrong?
OpenEMM Web services 2.0 require creation of creation of nonce, timestamp and password encryption. Official documentation is HERE
You have no nonce nor password encryption first try documentation example
if you need help with implementation - ask!

Categories