I have a question regarding the usage of 'AddServiceEndpoint' method of the 'ServiceHost' class.
It seems that adding a value to the 'address' parameter part of this method does not work.
Please refer to the code excerpt below:
Uri httpUrl = new Uri("http://localhost:8090/DuplexServer/SimpleCalculator");
host.AddServiceEndpoint(typeof(DuplexServer.ICalculatorDuplex), new WSDualHttpBinding(), "");
Here, in order to test, I can access this URL through a Web Browser:
http://localhost:8090/DuplexServer/SimpleCalculator and a webpage successfully shows.
However, if I implemented it this way instead:
Uri httpUrl = new Uri("http://localhost:8090/DuplexServer/");
host.AddServiceEndpoint(typeof(DuplexServer.ICalculatorDuplex), new WSDualHttpBinding(), "SimpleCalculator");
When I access : http://localhost:8090/DuplexServer/SimpleCalculator, a blank page appears.
The method is being run in the host project's file, which is a console app.
Whole code as requested:
class Program
{
static void Main(string[] args)
{
//Create a URI to serve as the base address
Uri httpUrl = new Uri("http://localhost:8090/DuplexServer/SimpleCalculator");
//Create ServiceHost
ServiceHost host = new ServiceHost(typeof(DuplexServer.CalculatorService), httpUrl);
//Add a service endpoint
host.AddServiceEndpoint(typeof(DuplexServer.ICalculatorDuplex), new WSDualHttpBinding(), "");
//Enable metadata exchange
/*
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
*/
//Start the Service
host.Open();
Console.WriteLine("Service is host at " + DateTime.Now.ToString());
Console.WriteLine("Host is running... Press <Enter> key to stop");
Console.ReadLine();
}
}
I would like to know the proper way to use the 'Address' parameter of this method.
Thanks.
Related
I am new to programming and i have given a project which i have no idea how will to it.
I have to write a host application.The following is the requirement:
Develop CXML webservice host for testing CXML posts from xyz.net .
The application should read the stream of data,validate against the dtd. store it in to the corresponding tables and send a response back to the client.
This should help you for example. create a console application, and set the startup object to SelfHost. Run the application and you wcf service should be available at the URL stated into the code : http://localhost:1234/hello"
[ServiceContract()]
public interface IIndexer
{
[OperationContract]
bool Test();
}
public class Indexer : IIndexer
{
public bool Test()
{
return true;
}
}
class SelfHost
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:1234/hello");
// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(Indexer), baseAddress))
{
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// Open the ServiceHost to start listening for messages. Since
// no endpoints are explicitly configured, the runtime will create
// one endpoint per base address for each service contract implemented
// by the service.
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press Q and <Enter> to stop the service.");
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
}
}
I want to create a class that implementing 2 service contracts, and exposing 2 end-points on different ports (I get the ports as input to the program).
My question is very similar to this question, but I want two end-points each one on different port.
EDIT:
Using this code:
var aConnectionString = "http://localhost:8200/A";
var bConnectionString = "http://localhost:8201/B";
ServiceHost host= new ServiceHost(typeof(abImp));
var binding = new BasicHttpBinding();
host.AddServiceEndpoint(typeof(A), binding, aConnectionString);
host.AddServiceEndpoint(typeof(B), binding, bConnectionString);
{
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpBinding(),
aConnectionString
);
}
host.Open();
I'm getting this error message on the host.Open() operation:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll
Additional information: A binding instance has already been associated to listen URI 'http://localhost:8200/A'. If two endpoints want to share the same ListenUri, they must also share the same binding object instance. The two conflicting endpoints were either specified in AddServiceEndpoint() calls, in a config file, or a combination of AddServiceEndpoint() and config.
SOLUTION
var aConnectionString = "http://localhost:" + portA+ "/A";
var bConnectionString = "http://localhost:" + portB+ "/B";
ServiceHost aHost = new ServiceHost(instance, new Uri(aConnectionString));
ServiceHost bHost = new ServiceHost(instance, new Uri(bConnectionString));
aHost.Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
bHost.Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
aHost.AddServiceEndpoint(typeof(A), new BasicHttpBinding(), aConnectionString);
bHost.AddServiceEndpoint(typeof(B), new BasicHttpBinding(), bConnectionString);
{
// Check to see if the service host already has a ServiceMetadataBehavior
var smb = aHost.Description.Behaviors.Find<ServiceMetadataBehavior>() ?? new ServiceMetadataBehavior();
aHost.Description.Behaviors.Add(smb);
aHost.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpBinding(),
aConnectionString + "/Mex"
);
}
{
// Check to see if the service host already has a ServiceMetadataBehavior
var smb = bHost.Description.Behaviors.Find<ServiceMetadataBehavior>() ?? new ServiceMetadataBehavior();
bHost.Description.Behaviors.Add(smb);
bHost.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpBinding(),
bConnectionString + "/Mex"
);
}
aHost.Open();
bHost.Open();
Given that you want two completely different addresses, only same implementation class, I'd recommend use of two different ServiceHost instances.
I'm trying to expose an interface through NetNamedPipeBinding.
Here's what I do:
try
{
//load the shedluer static constructor
ServiceHost svh = new ServiceHost(typeof(MyClass));
var netNamedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
var netNamedPipeLocation = "net.pipe://localhost/myservice/";
svh.AddServiceEndpoint(typeof(IMyInterface), netNamedPipeBinding, netNamedPipeLocation);
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = svh.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
smb = new ServiceMetadataBehavior();
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
svh.Description.Behaviors.Add(smb);
// Add MEX endpoint
svh.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexNamedPipeBinding(),
netNamedPipeLocation + "/mex"
);
svh.Open();
Console.WriteLine("Service mounted at {0}", netNamedPipeLocation);
Console.WriteLine("Press ctrl+c to exit");
ManualResetEvent me=new ManualResetEvent(false);
me.WaitOne();
svh.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception");
Console.WriteLine(e);
}
The service starts ok, but when I create a new Visual Studio project and try to add a service reference at location net.pipe://localhost/myservice/, I get following error:
The URI prefix is not recognized.
Metadata contains a reference that cannot be resolved: 'net.pipe://localhost/myservice/'.
Metadata contains a reference that cannot be resolved: 'net.pipe://localhost/myservice/'.
If the service is defined in the current solution, try building the solution and adding the service reference again.
If I substitute NetNamedPipeBinding for TcpBinding, the code works ok, and service reference can be added.
What should I change, so I can add service references in Visual Studio?
With var netNamedPipeLocation = "net.pipe://localhost/myservice/"; netNamedPipeLocation + "/mex" winds up being net.pipe://localhost/myservice//mex. Your AddServiceEndPoint call should be
svh.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexNamedPipeBinding(),
netNamedPipeLocation + "mex"
);
After removing the extra / I was able to connect to a local named pipe service hosted using your code without issue.
I am writing WCF Service - Client. The service is getting the endpoint url as arg, This is Windows Form Application.
The Service impl is:
BaseAddress = new Uri(args[0]);
using (ServiceHost host = new ServiceHost(typeof(DriverService), BaseAddress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
//host.AddServiceEndpoint(typeof(DriverService), new BasicHttpBinding(), BaseAddress);
host.Open();
After host.Open() i get the error, When i wrote same wcf code on another solution it worked just fine, i had the client and service. now i just need to open the service when wait until the client connects.
From what I understand, this is Service and i give it address, then it listens on the given address and exposing the methods on the interface to different clients.
Error:
Service 'DriverHost.DriverService' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.
Code of interface and class:
[ServiceContract]
public interface IDriverService
{
[OperationContract]
string WhoAmI();
}
public class DriverService : IDriverService
{
public string WhoAmI()
{
return string.Format("Im on port !");
}
}
since there is different between .net 4.5 and 3.5 i understand there is no default Endpoints.
So needed to declare:
BaseAddress = new Uri(args[0]);
using (ServiceHost host = new ServiceHost(typeof(Namespace.Classname), BaseAddress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.AddServiceEndpoint(typeof(Namespace.IInterface), new BasicHttpBinding(), args[0]);
host.Open();
Meaning - add the .AddServiceEndpoint(..)
and make sure that on ServiceHost() write the class, and on AddServiceEndpoint enter the Interface.
I create my host with the endpointaddress it needs to use, like this:
Uri endpointAddress = new Uri("http://127.0.0.1:5555/MyService");
ServiceHost host = new ServiceHost(myServiceType, endpointAddress);
host.AddServiceEndpoint(implementedContract, basicHttpBinding, string.Empty);
but when I later do host.Open(); I get the exception "HTTP could not register URL http://+:80/MyService/ because TCP port 80 is being used by another application". The result is the same when I do
host.AddServiceEndpoint(implementedContract, basicHttpBinding, endpointAddress);
Why would it try to do anything with port 80? How can I solve this?
Update
While trying to provide a more complete code sample, I found the culprit. I added a ServiceMetadataBehavior as follows:
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.ExternalMetadataLocation = new Uri(this.ExternalMetadataLocation);
smb.HttpGetEnabled = true;
smb.HttpGetUrl = this.RemovePort(this.EndpointAddress);
host.Description.Behaviors.Add(smb());
It seems that in the past I needed to remove the port from the URL to get this to work, but now that's exactly what causes the problem.
So Pratik is right: metadata were the problem, and of course the problem with port 80 is that there's some newly installed application using that port.
Thanks, regards,
Miel.
This is because port 80 is already used by another applicatiion as the error message says, most likely by local IIS server. Try stopping IIS and see, or use another port.
On vista and above you can use netsh command to check which ports are already reserved
BTW do you have http metadata or mex endpoints in the app.config or web.config file ?
The following works fine for me:
class Program
{
[ServiceContract]
public interface IMyService
{
[OperationContract]
void Test();
}
public class MyService : IMyService
{
public void Test()
{
throw new NotImplementedException();
}
}
static void Main()
{
var endpointAddress = new Uri("http://127.0.0.1:5555/MyService");
using (var host = new ServiceHost(typeof(MyService), endpointAddress))
{
var basicHttpBinding = new BasicHttpBinding();
host.AddServiceEndpoint(typeof(IMyService), basicHttpBinding, string.Empty);
host.Open();
}
}
}
Maybe you have some other code which is interfering?