I have a solution with three projects in C#:
CareLife.DataLayer ( Class Library )
CareLife.ServiceLayer ( WCF Service Application)
CareLife.BusinessLayer ( Serive Library )
I added the .dll (located obj folder) of project CareLife.BusinessLayer in the CareLife.ServiceLayer because of need to access methods of BusinessLayer in the project ServiceLayer.
namespace CareLife.BusinessLayer.Operations
{
public class SpecialityServices
{
void GetArea() { }
}
}
and....
namespace CareLife.ServiceLayer
{
[ServiceContract]
public class SpecialityOperations
{
[OperationContract]
[WebInvoke(UriTemplate="Area", Method="GET")]
ICollection<Area> GetArea()
{
try
{
SpecialityServices specialityServices = new SpecialityServices();
}
catch (Exception)
{
throw;
}
return null;
}
}
}
The question is: WHY when I Go to definition in the ServiceLayer of class SpecialityServices, I always am redirect to metadata class?
Have you tried adding it as a project reference instead of a dll from the obj folder ?
The resource I see defined here is Area. Are you doing a GET on http://<serviceRoot>/Area ?
Also, if you're building a rest service, why not use WebAPI?
You should explicitly declare webHttp endpoint. Here is sample system.serviceModel config section:
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<endpoint address="basic" binding="basicHttpBinding" contract="WcfService1.IService1" />
<endpoint address="" binding="webHttpBinding" contract="WcfService1.IService1" behaviorConfiguration="web"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Just to clarify, i am adding endpointBehaviors section and webHttp endpoint to service section
Related
Im trying to host to different service implementations of the same contract:
The reason is that need a dummy implementation for out-of-the-house testing.
Im trying to host both in the same WindowsService:
private ServiceHost _host;
private ServiceHost _dummy;
protected override void OnStart(string[] args)
{
_host = new ServiceHost(typeof(Service));
_host.Open();
//trying to avoid the app.config beeing used - because its already been hoste by _host
_dummy = new ServiceHost(typeof(TestDummyService));
_dummy.Description.Endpoints.Clear();
_dummy.AddServiceEndpoint(typeof(IService),
new WebHttpBinding(),
#"<link>/Dummy.svc/");
_dummy.ChannelDispatchers.Clear();
_dummy.Open();
}
This is the config file:
<system.serviceModel>
<services>
<service name="namespace.Service">
<host>
<baseAddresses>
<add baseAddress="<link>/Service.svc"/>
</baseAddresses>
</host>
<endpoint address=""
binding="webHttpBinding"
contract="namespace.IService"
behaviorConfiguration="web" />
<endpoint address="/mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors >
<behavior>
<serviceMetadata httpGetEnabled="true"
httpGetUrl="<link>/Service.svc/About" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name ="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
The ChannelDispatcher at /Service.svc/About with Contracts ‘IHttpGetHelpPageAndMetadataContract’ is unable to open.
any help is appreciated.
Update 1
My goal is to have 2 different implementations of the same contract (IService) hosted in one WindowsService.
I would also like to configure both of them in the config file.
Well i would like to know what's the business scenario. All I guess is, the client should not know the implementation, its just the URL of the service would indicate (or route) to the implementation.
Kindly clarify.
Refer to this existing post and let
me know if it makes sense.
The above post is hinting the implementation, refer to this post for deployment details.
so i found out, that even thow the testdummy service was added programatic, it still got the service metadatabehavior.
My solution was to not make the dehavior default - given it at name:
app.config:
<service name="namespace.Service" behaviorConfiguration="someName">
//.. later:
<behavior name="someName">
<serviceMetadata httpGetEnabled="true"
httpGetUrl="<link>/Service.svc/About" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
The rest of the code, statyed the same
Can't you add another endpoint and fill in the adress with a distinct name:
<endpoint address="/SecondService"
binding="webHttpBinding2"
contract="namespace.IService"
/>
Url becomes /Service.svc/SecondService
I have a WCF service and a Silverlight 5 client.
I've defined the following interfaces:
[ServiceContract(Namespace = "Silverlight", CallbackContract = typeof(IDuplexClient))]
public interface IDuplexService
{
[OperationContract]
void Subscribe(string userId);
[OperationContract]
void Unsubscribe(string userId);
}
[ServiceContract]
public interface IDuplexClient
{
[OperationContract(IsOneWay = true)]
void PushNotification(string msg);
}
And this is my Web.config file:
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
When I try to run the service I get:
The service '/ServerService.svc' cannot be activated due to an exception during compilation. The exception message is: Contract requires Duplex, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support it.
I know I need to add some properties to Web.config, but wherever I looked (and whatever I tried) I couldn't make it work.
I'm new to WCF and I'd like your help on that subject. All my googling lead me nowhere and the answers people who asked here the same question got doesn't work for me.
So I've decided to give up searching and just ask.
Update: I used this link to create the interface - http://msdn.microsoft.com/en-us/library/cc645027%28v=vs.95%29.aspx
If that is the extent of your web.config configuration for WCF, then you are missing the section that defines your contract:
<services>
<service name="WebApplication1.Service1">
<endpoint address="" binding="wsDualHttpBinding" contract="WebApplication1.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
If you do have this section specified, the other likely cause is that the contract name is not fully qualified; it must include the full namespace and not just the name of the contract.
Here is the full System.ServiceModel configuration:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service name="WebApplication1.Service1">
<endpoint address="" binding="wsHttpBinding" contract="WebApplication1.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
In this case, the application namespace is WebApplication1, the service's class name is Service1 (i.e. Service1.svc) and the interface that Service1 implements is IService1.
I have created the simple web service.
Code:
[ServiceContract]
public interface ITsdxService
{
[OperationContract]
void DoWork();
[OperationContract]
string Test();
}
public class TsdxService : ITsdxService
{
public void DoWork()
{
}
public string Test()
{
return "Hello World!";
}
}
Web.config:
<system.serviceModel>
<services>
<service name="Test.TSDX.UI.TsdxService">
<endpoint
address="Tsdx"
binding="wsHttpBinding"
bindingConfiguration="TestBinding"
contract="Test.TSDX.UI.ITsdxService" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="TestBinding" />
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
When I run from Visual Studio I put localhost:50517/TsdxService.svc?wsdl all works fine - I can see wsdl, but when I put localhost:50517/TsdxService.svc/Tsdx/Test or localhost:50517/TsdxService.svc/Tsdx/DoWork I don't see anything. The Fiddler tells me that I got 400 error. Breakpoints (on Test and DoWork methods) don't work. Why? What did I do incorrect?
Add the WebGet attribute to your service operations.
[WebGet]
public string Test()
{
...
}
For this to work, you also need to add WebScriptEnablingBehavior to the service configuration. Also, use the webHttpBinding. These things are all required to allow the service to work as an AJAX service.
Definition:
<endpointBehaviors>
<behavior name="EndpointBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
Reference:
<endpoint behaviorConfiguration="EndpointBehavior"
binding="webHttpBinding"
...
/>
I am trying to make a simple WCF RESTful for the first time to be consumed via JSON. I have my interface below, but what would be the URL I would call to invoke my MemberLogon() method?
I thought it would be this:
http://localhost:49701/Exchange.svc/?membershipNumber=6519548&blah=abc
but I get a 404. I have a feeling it is to do with my service configuraiton in my Web.Config. Help!
My interface and class is:
[ServiceContract]
public interface IExchange
{
[System.ServiceModel.OperationContract(Name = "MemberLogon")]
[WebInvoke(UriTemplate = "/?membershipNumber={membershipNumber}&blah={blah}", Method = "GET", ResponseFormat = WebMessageFormat.Json)]
Member MemberLogon(string membershipNumber, string blah);
}
[System.Runtime.Serialization.DataContract]
public class Member
{
[System.Runtime.Serialization.DataMember]
public string Username { get; set; }
}
Configuration is:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyNamespace.MyClass.ExchangeBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyNamespace.MyClass.ExchangeBehavior" name="MyNamespace.MyClass.Exchange">
<endpoint address="" binding="webHttpBinding" contract="MyNamespace.MyClass.IExchange" />
</service>
</services>
The code and interface look good. Can you try this configuration?
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="MyNamespace.MyClass.ExchangeBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="MyNamespace.MyClass.Exchange">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="MyNamespace.MyClass.ExchangeBehavior" contract="MyNamespace.MyClass.IExchange" />
</service>
</services>
</system.serviceModel>
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").