WCF service throws InvalidOperationException - c#

i was trying to create basic WCF service and host it on a console application.
Here's my code of WCF project.
ISampleService.cs
using System.ServiceModel;
namespace MultipleSeviceContractAppl
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "ISampleService" in both code and config file together.
[ServiceContract]
public interface ISampleService
{
[OperationContract]
string DoWork();
}
}
SampleService.cs
namespace MultipleSeviceContractAppl
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "SampleService" in both code and config file together.
public class SampleService : ISampleService
{
public string DoWork()
{
return "Message from WCFservice";
}
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="MultipleSeviceContractAppl.SampleService" behaviorConfiguration="mexBehaviour">
<endpoint address="SampleService" binding="netTcpBinding" contract="MultipleSeviceContractAppl.ISampleService">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/"/> <!--For metadata exchange-->
<add baseAddress="net.tcp://localhost:8737/" /> <!--Endpoint, netTCP binding, For data exchange-->
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
WCF Hosting on console appl - Program.cs
using System;
using System.ServiceModel;
namespace ConsumeWCFApplicationAppl
{
class Program
{
static void Main()
{
using (ServiceHost host = new ServiceHost(typeof(MultipleSeviceContractAppl.SampleService)))
{
host.Open();
Console.WriteLine("Host started #" + DateTime.Now.ToString());
Console.ReadKey();
}
}
}
}
in console application at line host.Open();, following exception was thrown.
An unhandled exception of type 'System.InvalidOperationException'
occurred in System.ServiceModel.dll Additional information: Service
'MultipleSeviceContractAppl.SampleService' 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. Help me to
figure out my mistake. Thanks

You need to replicate the config in your console app and add reference to DLL of the service model assemblies to this project...
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="MultipleSeviceContractAppl.SampleService" behaviorConfiguration="mexBehaviour">
<endpoint address="SampleService" binding="netTcpBinding" contract="MultipleSeviceContractAppl.ISampleService">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/"/> <!--For metadata exchange-->
<add baseAddress="net.tcp://localhost:8737/" /> <!--Endpoint, netTCP binding, For data exchange-->
</baseAddresses>
</host>
</service>
</services>

Related

CoreWCF -The contract name could not be found in the list of contracts implemented by the service

I use this configuration for CoreWCF.
=>.NET Framework 4.7.2
=> CoreWCF Namespace
Here is my Web config
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="bhv">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="HelloService.HelloService" behaviorConfiguration="bhv">
<endpoint address="" binding="basicHttpBinding" contract="HelloService.IHelloService"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
</system.serviceModel>
using System;
using CoreWCF;
namespace HelloService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IHelloService" in both code and config file together.
[ServiceContract]
public interface IHelloService
{
[OperationContract]
void DoWork();
}
}
using System;
using CoreWCF;
namespace HelloService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "HelloService" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select HelloService.svc or HelloService.svc.cs at the Solution Explorer and start debugging.
public class HelloService : IHelloService
{
public void DoWork()
{
}
}
}
I have added the service code here as well.
What might have gone wrong to make this service up?

WCF REST GET returns "Endpoint not found"

So I am trying to create a very basic WCF service with REST GET but there is only "Endpoint not found". I am sending GET via Postman App to address:
http://localhost:8733/Design_Time_Addresses/RESTfulTest/Service1/json
Service is hosted by IIS; Here's all my code:
namespace RESTfulTest
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet]
string GetText();
}
}
namespace RESTfulTest
{
[ServiceBehavior(InstanceContextMode =InstanceContextMode.Single)]
public class Service1 : IService1
{
public string GetText()
{
return "Hello REST";
}
}
}
And App.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service name="RESTfulTest.Service1">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8733/Design_Time_Addresses/RESTfulTest/Service1/" />
</baseAddresses>
</host>
<endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="RESTfulTest.IService1"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
What am I missing here?
Are you going to be using ASP.NET Ajax to call the service? If not, you should not be using the <enableWebScript> behavior, but rather the <webHttp> behavior.
Also, you should probably remove the <serviceMetadata> behavior, since you won't be exposing WSDL from your service.
So everything was set up properly. The endpoint address that I was asking was incorrect. It should be http://localhost:8733/Design_Time_Addresses/RESTfulTest/Service1/json/GetText
I didn't know that function name should be added to the address, that's the point.

"Unable to Download Metadata" when using Two Bindings

In my book, it wants me to expose two endpoints using two bindings: WsHttpBinding & NetTCPBinding and host the service in a host application.
I use the following code in C# to try to connect to my service:
Uri BaseAddress = new Uri("http://localhost:5640/SService.svc");
Host = new ServiceHost(typeof(SServiceClient), BaseAddress);
ServiceMetadataBehavior Behaviour = new ServiceMetadataBehavior();
Behaviour.HttpGetEnabled = true;
Behaviour.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
Host.Description.Behaviors.Add(Behaviour);
Host.Open();
On the service side I have:
[ServiceContract]
public interface IService...
public class SService : IService....
Then in my Config file I have:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="WsHttpBehaviour" name="SService.SService">
<endpoint
address=""
binding="wsHttpBinding"
bindingConfiguration="WsHttpBindingConfig"
contract="SService.IService" />
<endpoint
address=""
binding="netTcpBinding"
bindingConfiguration="NetTCPBindingConfig"
contract="SService.IService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:5640/SService.svc" />
<add baseAddress="net.tcp://localhost:5641/SService.svc" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
But when I try to add service reference to my host application, it says unable to download metadata from the address. I don't understand what is wrong and the teacher never taught this.. I decided to go ahead and look it up and learn ahead of time. I used the Editor to create the WebConfig shown above.
Can anyone point me in the right direction? I added Metadata behaviour through the editor and I set the HttpGetEnabled to true.
I can find a few issues with your code that can cause this issue:
Host = new ServiceHost(typeof(SServiceClient), BaseAddress). Pass here typeof(SService.SService) instead of typeof(SServiceClient). Change like this:
Host = new ServiceHost(typeof(SService.SService))
<service behaviorConfiguration="WsHttpBehaviour". I guess this should be "Behavior" as you have defined that. Since you have metadata enabled in config, you may remove the lines of code which add a ServiceMetadataBehavior to your servicehost.
Here is a sample that you can use for reference:
<system.serviceModel>
<services>
<service name="ConsoleApplication1.Service">
<endpoint address="" binding="wsHttpBinding" contract="ConsoleApplication1.IService" />
<endpoint address="" binding="netTcpBinding" contract="ConsoleApplication1.IService" />
<host>
<baseAddresses>
<add baseAddress="http://<machinename>:5640/SService.svc" />
<add baseAddress="net.tcp://<machinename>:5641/SService.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(Service));
host.Open();
Console.ReadLine();
}
}
[ServiceContract]
public interface IService
{
[OperationContract]
string DoWork();
}
public class Service : IService
{
public string DoWork()
{
return "Hello world";
}
}
}
Metadata will be automatically available at the http baseaddress defined in the config.

Firing Event in WCF Host

I'm running a WCF service hosted in a WPF app, and am trying to raise an event in the host when a message is sent to the service, but am having great difficulty.
My code is as follows:
Service -
namespace BatService
{
[ServiceContract]
public interface IBatServ
{
[OperationContract]
void UseGadget(string name);
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class BatServ : IBatServ
{
public void UseGadget(string name)
{
OnUsedGadget(name);
}
public static event EventHandler<BatArgs> UsedGadget;
public static void OnUsedGadget(string name)
{
if (UsedGadget != null)
UsedGadget(null, new BatArgs() { BatGadget = name });
}
}
public class BatArgs : EventArgs
{
public string BatGadget;
}
}
Host -
namespace BatHostWPF
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ServiceHost host = new ServiceHost(typeof(BatServ));
BatServ.UsedGadget += new EventHandler<BatArgs>(BatServ_UsedGadget);
host.Open();
}
void BatServ_UsedGadget(object sender, BatArgs e)
{
MessageBox.Show(e.BatGadget + " was used!");
}
}
}
Service App.config -
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="BatService.BatServ">
<endpoint address="" binding="wsHttpBinding" contract="BatService.IBatServ">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/BatService/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Host's App.config -
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior0">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="NewBehavior0" name="BatService.BatServ">
<clear />
<endpoint address="net.pipe://localhost/battserv" binding="netNamedPipeBinding"
bindingConfiguration="" contract="BatService.IBatServ" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8888/batserv" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
As you can probably guess, I'm expecting to see a MessageBox when I call UseGadget() from a client. Whenever I try to test it out with VS's WcfTestClient.exe, nothing seems to happen at all. Where am I going wrong?
It turns out my endpoints weren't configured correctly. This page helped me solve my problems - http://www.switchonthecode.com/tutorials/wcf-tutorial-basic-interprocess-communication
I'm not sure if you can "raise events" in wcf, but you can create duplex communication architectures. The netTCPBinding, netNamedPipBinding and wsDualHttpBinding support this functionality.
Here is a video demonstration how to do callbacks with the wsDualHttpBinding
http://www.youtube.com/watch?v=NO2JsLrP75E
I've never done this with netNamedPipeBinding, but i assume the procedure is similar.
Remember to update your app.config files and service references when you're done with your implementation.
Hope that helps!

Service can't find endpoint of other service in WCF

I am trying to create two WCF services which should be able to access each other. However I am getting this error message:
The server encountered an error processing the request. The exception message is 'Could not find default endpoint element that references contract 'AddonWCFService.IService1' 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.'.
I call the Test() Method from this service
namespace CustomersService
{
[ServiceContract]
public interface ICustomers
{
[OperationContract]
[WebGet]
string Test();
}
public class Customers : ICustomers
{
private int m_i = 0;
public int GetCounter()
{
return m_i;
}
public void Test()
{
AddonWCFService.Service1Client foo = new AddonWCFService.Service1Client();
}
}
}
The other service
namespace AddonWCFWebservice
{
[ServiceContract]
public interface IService1
{
[OperationContract]
void Init();
}
public class Service1 : IService1
{
public void Init()
{
}
}
}
My webconfig:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="MyserviceBehavior" name="CustomersService.Customers">
<endpoint name="ws" address="ws" binding="wsHttpBinding" contract="CustomersService.ICustomers"/>
<endpoint name=""
address=""
binding="webHttpBinding"
contract="CustomersService.ICustomers"
behaviorConfiguration="WebBehavior"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="AddonWCFWebservice.Service1" behaviorConfiguration="MyserviceBehavior">
<endpoint address="" binding="wsHttpBinding" contract="AddonWCFWebservice.IService1"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyserviceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
<customErrors mode="Off"/>
</system.web>
</configuration>
Both services reside in the same active directory of IIS . I added the service reference to the VS C# projects using the web URL i.e. http://www.foobar.baz/Test/Service1.svc and http://www.foobar.baz/Test/Customers.svc
It's probably something obvious but I'm fairly new to the whole WCF business. Thanks!
Update: The solution was to add a client section to my webconfig. Also I used basicHttpBinding over wsHttpBinding because my security will be incorparated elsewhere because it is a public service. I had to match the binding of the client to the binding of the service section: both basicHttpBinding
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<client>
<endpoint
name=""
address="http://demo.mydomain.baz/TestService/Service1.svc"
binding="basicHttpBinding"
contract="AddonWCFService.IService1" />
</client>
<services>
<service behaviorConfiguration="MyserviceBehavior" name="CustomersService.Customers">
<endpoint name="ws" address="ws" binding="wsHttpBinding" contract="CustomersService.ICustomers"/>
<endpoint name=""
address=""
binding="webHttpBinding"
contract="CustomersService.ICustomers"
behaviorConfiguration="WebBehavior"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="AddonWCFWebservice.Service1" behaviorConfiguration="MyserviceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="AddonWCFWebservice.IService1"/>
<!--
<endpoint address=""
binding="webHttpBinding"
contract="AddonWCFWebservice.IService1"
behaviorConfiguration="WebBehavior"/>
-->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyserviceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
<customErrors mode="Off"/>
</system.web>
</configuration>
The problem with your config is that you have no client configurations. You have only server parts. You need to have client element with endpoints. Take a look here: http://msdn.microsoft.com/en-us/library/ms731745.aspx
If you are not so sure about you config skills I would advise you to open your config with SvcConfigEditor.exe. You will immediately see what's configured.
You can find it here: C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\SvcConfigEditor.exe.
If you will do it - you will see that there are no clients configured
I think you specified the wrong service contract in your config file.
This line here:
<endpoint address="" binding="wsHttpBinding" contract="AddonWCFWebservice.IService1"/>
specifies the contract as "AddonWCFWebservice.IService1" when it should be something like "AddonService.IService1" (without the "WCF").

Categories

Resources