WCF client unable to connect to WCF server with error - c#

I am unable to connect my WCF client to my WCF server on a Localhost network. The error that I am getting is the following:
Error while connecting to the Localhost server: Could not find default
endpoint element that references contract 'MyServiceReference.IMyService'
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.
The server connection is the following. Here is the code:
_host = new ServiceHost(typeof(MyService));
//Create Metadata exchange for the service
ServiceMetadataBehavior mexBehavior = new ServiceMetadataBehavior();
_host.Description.Behaviors.Add(mexBehavior);
//Add service endpoints for the service and mex
_host.AddServiceEndpoint(typeof(IMyService), new NetNamedPipeBinding(), "net.pipe://localhost/WFC_Server/MyService.svc");
_host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexNamedPipeBinding(), "net.pipe://localhost/WFC_Server/MyService.svc/mex");
_host.Open();
I am not setting up my client to connect to the server properly. Does anybody know why? Here is the code:
var callback = new MyServiceCallback();
var instanceContext = new InstanceContext(callback);
var client = new MyServiceReference.MyServiceClient(instanceContext);
client.Endpoint.Address = new EndpointAddress("net.pipe://localhost/WFC_Server/MyService.svc");
client.OpenSession();
Does anybody know why my client does not connect to the server?

I have replicated the problem and fixed the issue.
1. Specify the endpoint address while creating the client.
var callback = new MyServiceCallback();
var instanceContext = new InstanceContext(callback);
EndpointAddress remoteAddress = new EndpointAddress("net.pipe://localhost/WFC_Server/MyService.svc");
var client = new MyServiceClient(instanceContext,new NetNamedPipeBinding(),remoteAddress);
client.Hello(); // call the function
In the server, you can register like this:
Code:
Uri address1 = new Uri("http://localhost/WFC_Server/");
Uri address2 = new Uri("net.pipe://localhost/WFC_Server/");
ServiceHost _host = new ServiceHost(typeof(MyService), address1,address2);
//Create Metadata exchange for the service
ServiceMetadataBehavior mexBehavior = new ServiceMetadataBehavior();
mexBehavior.HttpGetEnabled = true;
_host.Description.Behaviors.Add(mexBehavior);
//Add service endpoints for the service and mex
_host.AddServiceEndpoint(typeof(IMyService), new NetNamedPipeBinding(), "MyService.svc");
_host.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpBinding(),
"mex"
);
_host.Open();
I have used the following interfaces as an example:
class MyService : IMyService
{
public void Hello()
{
Console.WriteLine("Hello From Server..");
}
}
[ServiceContract(CallbackContract = typeof(ICallbackService))]
internal interface IMyService
{
[OperationContract]
void Hello();
}
[ServiceContract]
public interface ICallbackService
{
[OperationContract]
void CallClient();
}

Related

Programmatically have Client application list a WCF service's Endpoints created during runtime using a URL (like WCF Test Client does)

Maybe I'm not searching with the right terms because this seems pretty simple. I'm just looking for a way to list the endpoints of a WCF service that has it's endpoints created during runtime the same way WCF Test Client Does.
Specify URL
Get MetaData and Endpoints
This is how I add the endpoints during runtime
string SetInstrumentsURL = serviceUrl + "SetInstruments/";
string SetInstrumentsPipe = "net.pipe://localhost/TestService/SetInstruments/";
ServiceHost SetInstrumentsHost = null;
var SetInstruments = InstrumentLoader.Factory.GetIEnumerableOf<ISetInstrument>();
if (SetInstruments.Count() > 0)
{
Uri SetInstrumentsURI = new Uri(SetInstrumentsURL);
Uri SetInstrumentsPipedURI = new Uri(SetInstrumentsPipe);
NetTcpBinding netTcpBindingSetInstruments = new NetTcpBinding();
NetNamedPipeBinding NamedPipeBindingSetInstruments = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
SetInstrumentsHost = new ServiceHost(typeof(TeraSetInstrumentService), new Uri[] { SetInstrumentsURI, SetInstrumentsPipedURI });
ServiceMetadataBehavior SetInstrumentServiceMetadataBehavior = new ServiceMetadataBehavior();
SetInstrumentsHost.Description.Behaviors.Add(SetInstrumentServiceMetadataBehavior);
SetInstrumentsHost.AddServiceEndpoint(typeof(IMetadataExchange),
MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
SetInstrumentsHost.AddServiceEndpoint(typeof(IMetadataExchange),
MetadataExchangeBindings.CreateMexNamedPipeBinding(), "mex");
foreach (var setter in SetInstruments)
{
SetInstrumentsHost.AddServiceEndpoint(typeof(ISetInstrumentService), netTcpBindingSetInstruments, SetInstrumentsURL + setter.Name).Name = "Set_" + setter.Name.Replace(" ", "_");
SetInstrumentsHost.AddServiceEndpoint(typeof(ISetInstrumentService), NamedPipeBindingSetInstruments, SetInstrumentsPipe + setter.Name).Name = "Set_" + setter.Name.Replace(" ", "_");
}
SetInstrumentsHost.Open();
}
What functions can I use from the client side to access those same endpoints as WCF Test Client? I know how to connect to those endpoints if I already have the Endpoint's URL but I would like to have a list of the endpoints so I can create a drop down list choose from that changes depending on what host you connect to.
Adding a service reference through Visual Studio doesn't list all of the endpoints because the are not created yet. Is the a library I can use to get them at run time like WCF Test Client does.
Provided that we have the service metadata URI, we could use MetadataExchangeClientMode and MetadataResolver class which is provided in the System.ServiceModel.Description namespace to retrieve and process the metadata.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-metadataresolver-to-obtain-binding-metadata-dynamically
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-metadataexchangeclient-to-retrieve-metadata
I have made a simple example, wish it is useful to you.
class Program
{
static void Main(string[] args)
{
Uri uri = new Uri("http://10.157.13.69:3336/mex");
MetadataExchangeClient client = new MetadataExchangeClient(uri, MetadataExchangeClientMode.MetadataExchange);
MetadataSet metadata = client.GetMetadata();
WsdlImporter importer = new WsdlImporter(metadata);
ServiceEndpointCollection endpoints = importer.ImportAllEndpoints();
//ServiceEndpointCollection endpoints = MetadataResolver.Resolve(typeof(IService), uri, MetadataExchangeClientMode.MetadataExchange);
foreach (var item in endpoints)
{
Console.WriteLine(item.Address.Uri);
}
}
}
[ServiceContract]
public interface IService
{
[OperationContract]
string SayHello();
}
Result
Okay it was pretty easy to do, I just needed to use the MetadataExchangeClient to get the config. In the code all I had to do to get the MetaData Xml was this:
var meta = new System.ServiceModel.Description.MetadataExchangeClient(new Uri("net.tcp://10.0.2.124:9000/TeraService/SetInstruments/mex"), System.ServiceModel.Description.MetadataExchangeClientMode.MetadataExchange);
var data = meta.GetMetadata();
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(data.GetType());
TextWriter writer = new StreamWriter("xmlfile.xml");
x.Serialize(writer, data);
writer.Close();
I posted my answer in the wrong place. But Abraham Qian has a more elegant solution that I will test now.

WCF Application hosted service Faulted State exception?

No idea what's going on. Simple application hosted service. Ran fine on server A. Copied everything over to server B...and suddenly won't launch.
Any tips? Ideas? I'll happily provide more info. Thanks for any help.
Error message:
The communication object, System.ServiceModel.ServiceHost, cannot be
used for communication because it is in the Faulted state.
Code (FAILS AT HOST.OPEN()_
static void Main(string[] args)
{
try
{
Uri baseAddress = new Uri("http://localhost:8080/Brp");
Uri mexUri = new Uri("http://localhost:8080/Brp/mex");
// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(BBService), baseAddress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetUrl = mexUri;
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
BasicHttpBinding binding = new BasicHttpBinding();
binding.MaxReceivedMessageSize = int.MaxValue;
binding.Security.Mode = BasicHttpSecurityMode.None;
host.AddServiceEndpoint(typeof(IBService), binding, "");
// Enable metadata publishing.
var behavior = host.Description.Behaviors.Find<ServiceDebugBehavior>();
behavior.IncludeExceptionDetailInFaults = true;
host.Open();
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
} catch (Exception excep)
{
writeMessage("EXCEPTION!!! - " + excep.Message);
}
In case anyone else runs into this do: Right-click -> Run as administrator
You have to follow certain rules while working with Message contract
1. When using Message contract type as parameter, Only one parameter can be used in servicie Operation
[OperationContract]
void SaveEmployeeDetails(EmployeeDetails emp);
2. Service operation either should return Messagecontract type or it should not return any value
[OperationContract]
EmployeeDetails GetEmployeeDetails();
3. Service operation will accept and return only message contract type. Other data types are not allowed.
[OperationContract]
EmployeeDetails ModifyEmployeeDetails(EmployeeDetails emp);
Note: If a type has both Message and Data contract, service operation will accept only message contract.

C# BasicHttpBinding with BasicHttpSecurityMode.Transport for Silverlight client

i want to secure a Silverlight App with SSL.
So I try to wrote a proof of concept, where I host two BasicHttpBindings. One with BasicHttpSecurityMode.None and the other with BasicHttpSecurityMode.Transport.
But I not able to get the second one running, The WCFTestClient from VS Tools display this error message
// Error: Cannot obtain Metadata from https://localhost:8081/ If this is
// a Windows (R) Communication Foundation service to which you have
// access, please check that you have enabled metadata publishing at the
// specified address. For help enabling metadata publishing, please
// refer to the MSDN documentation at
// http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
// Error URI: https://localhost:8081/ Metadata contains a reference
// that cannot be resolved: 'https://localhost:8081/'. An error
// occurred while making the HTTP request to https://localhost:8081/.
// This could be due to the fact that the server certificate is not
// configured properly with HTTP.SYS in the HTTPS case. This could also
// be caused by a mismatch of the security binding between the client and
// the server. The underlying connection was closed: An unexpected
// error occurred on a send. Unable to read data from the transport
// connection: An existing connection was forcibly closed by the remote
// host. An existing connection was forcibly closed by the remote
// hostHTTP GET Error URI: https://localhost:8081/ There was an
// error downloading 'https://localhost:8081/'. The underlying
// connection was closed: An unexpected error occurred on a send.
// Unable to read data from the transport connection: An existing
// connection was forcibly closed by the remote host. An existing
// connection was forcibly closed by the remote host
I would be great if some could view over my code, I stuck for two days with this. It need to be done all programmatically.
Thanks a lot.
Almost the whole programm: http://pastebin.com/9j9K43tS
The Endpoints
private static readonly Uri UriBase = new Uri("http://localhost:8080/");
private static readonly Uri UriBaseService = new Uri("http://localhost:8080/Basic");
private static readonly Uri UriSecure = new Uri("https://localhost:8081/");
private static readonly Uri UriSecureService = new Uri("https://localhost:8081/Secure");
This Works
private static void BasicHTTPServer()
{
var binding = new BasicHttpBinding();
binding.Name = "binding1";
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.Security.Mode = BasicHttpSecurityMode.None;
// Create a ServiceHost for the CalculatorService type and provide the base address.
_serviceHost = new ServiceHost(typeof (ServiceBasic), UriBase);
_serviceHost.AddServiceEndpoint(typeof (IServiceBasic), binding, UriBaseService);
_serviceHost.AddServiceEndpoint(typeof (IPolicyRetriever), new WebHttpBinding(), "")
.Behaviors.Add(new WebHttpBehavior());
var smb = new ServiceMetadataBehavior {HttpGetEnabled = true, HttpGetUrl = UriBase};
_serviceHost.Description.Behaviors.Add(smb);
// Open the ServiceHostBase to create listeners and start listening for messages.
_serviceHost.Open();
Logger.Log(Server.Basic, string.Format("Open at {0} Service: {1}", UriBase, UriBaseService));
}
This doesn't Works
private static void SecureHTTPServer()
{
var binding = new BasicHttpBinding();
// it doesnt matter if I use BasicHttpsBinding or BasicHttpBinding
binding.Name = "binding2";
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
// Create a ServiceHost for the CalculatorService type and provide the base address.
_serviceHostSecure = new ServiceHost(typeof (ServiceBasic), UriSecure);
_serviceHostSecure.Credentials.ServiceCertificate.Certificate = GetCertificate();
//load a certificate from file
_serviceHostSecure.Credentials.ClientCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.None;
_serviceHostSecure.AddServiceEndpoint(typeof (IServiceBasic), binding, UriSecureService);
var webHttpBinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
webHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
_serviceHostSecure.AddServiceEndpoint(typeof (IPolicyRetriever), webHttpBinding, "")
.Behaviors.Add(new WebHttpBehavior());
var smb = new ServiceMetadataBehavior {HttpsGetEnabled = true, HttpsGetUrl = UriSecure};
_serviceHostSecure.Description.Behaviors.Add(smb);
// Open the ServiceHostBase to create listeners and start listening for messages.
_serviceHostSecure.Open();
Logger.Log(Server.Basic, string.Format("Open at {0} Service: {1}", UriSecure, UriSecureService));
}

Discovery endpoint not found, Timeout exception

I'm loading an host with a service called Service which implement the contract IService.
The binding is WSDualHttpBinding.
var host = new ServiceHost(typeof(Service));
host.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
host.AddServiceEndpoint(typeof(IService),new WSDualHttpBinding()
,endPointAddress);
In the client side i am trying to discover the endpoint.
EndpointAddress address = new EndpointAddress(new Uri(string.Format("http://{0}:{1}/Service/Client/Discovery", Environment.MachineName, "1111")));Environment.MachineName, 1111);
DiscoveryClient client =
new DiscoveryClient(new DiscoveryEndpoint(new WSDualHttpBinding(), address));
FindResponse find = client.Find(new FindCriteria(typeof(IService))
{ Duration = TimeSpan.FromSeconds(3) });
It is not working... I get a timeout exception after a minute without any reason.
i am running the host and the client on the same machine.
does anyone can detect what the problem is?
thanks

The provided URI scheme 'net.tcp' is invalid; expected 'http'

I'm a newbie at WCF. I'm trying to edit existing code to use a net.tcp binding instead of a http binding. I have done this easily in test projects using the config files, but for various reasons, in the real project it is done programatically.
I made the necessary changes, and the service host seems to start correctly:
Uri baseAdress= new Uri("net.tcp://localhost:7005/MyService/");
host = new ServiceHost(typeof(MyServiceImpl), baseAdress);
host.AddServiceEndpoint(
typeof(MyService),
new NetTcpBinding(),
"");
ServiceMetadataBehavior metadataBehavior;
metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (metadataBehavior == null)
{
metadataBehavior = new ServiceMetadataBehavior();
host.Description.Behaviors.Add(metadataBehavior);
}
BindingElement bindingElement = new TcpTransportBindingElement();
CustomBinding binding = new CustomBinding(bindingElement);
host.AddServiceEndpoint(typeof(IMetadataExchange), binding, "mex");
host.Open();
So far so good. I edited the connection string client side:
string serverUri = string.Format("net.tcp://{0}:{1}/MyService", serverName, port);
MyService server = new MyServiceClient("MYS", serverUri);
But when i try to call functions from my service, i get this error:
The provided URI scheme 'net.tcp' is invalid; expected 'http'
Not quite sure what i am missing... Any hints?

Categories