I've got a app.config file for my application which defines a series of web services similar to this:
<client>
<endpoint address="https://xxxxxx.local:12610/Applicationws.svc"
binding="basicHttpBinding" bindingConfiguration="test1"
contract="Applicationws.Applicationws" name="test1" />
<endpoint address="https://yyyyyy.local:12610/Applicationws.svc"
binding="basicHttpBinding" bindingConfiguration="test2"
contract="Applicationws.Applicationws" name="test2" />
<endpoint address="https://zzzzzz.local:12610/Applicationws.svc"
binding="basicHttpBinding" bindingConfiguration="test3"
contract="Applicationws.Applicationws" name="test3" />
</client>
I'd like to be able to add some extra attributes to each endpoint entry so I can easily identify it. These would be items such as Description, Type etc. and then be able to get this back in the ChannelEndpointElement object or similar e.g.
<endpoint address="https://zzzzzz.local:12610/Applicationws.svc"
binding="basicHttpBinding" bindingConfiguration="test3"
ontract="Applicationws.Applicationws" name="test3"
description="some web service" type="myappname" />
I've had a nose around the net and tried reading the docs but I cannot find anything close. Is it really such an unreasonable thing to want to do? My final thought is to append the extra attributes to the name value with a separator of some kind.
Related
I have multiple contracts in one WCF:
namespace SysLap.Services.Web.DataExtractor
{
[ServiceContract]
public interface IServiceDataExtractor
{
[OperationContract]
[WebGet]
List<User> GetAllUsers(/*CommonParams commonParams*/);
}
[ServiceContract]
public interface IScopesExtract
{
[OperationContract]
[WebGet]
List<SyScope> GetAllScopes();
}
}
and the Web.config is well configured:
<endpoint address="rest" behaviorConfiguration="restBehavior"
binding="webHttpBinding" contract="SysLap.Services.Web.DataExtractor.IServiceDataExtractor" />
<endpoint address="rest" behaviorConfiguration="restBehavior"
binding="webHttpBinding" contract="SysLap.Services.Web.DataExtractor.IScopesExtract" />
</service>
For the service GetAllUsers, it is worked very good. But for the service GetAllScopes, when i test it with SOAP UI, i am getting this error:
<p class="heading1">Request Error</p>
<p>The server encountered an error processing the request. The exception message is 'Multiple filters matched.'.
See server logs for more details. The exception stack trace is: </p>
<p> at System.ServiceModel.Dispatcher.EndpointDispatcherTable.LookupInCache(Message message, Boolean&
addressMatched)
at System.ServiceModel.Dispatcher.EndpointDispatcherTable.Lookup(Message message, Boolean&
addressMatched)
at System.ServiceModel.Dispatcher.ChannelHandler.GetDatagramChannel(Message message, EndpointDispatcher&
endpoint, Boolean& addressMatched)
at System.ServiceModel.Dispatcher.ChannelHandler.EnsureChannelAndEndpoint(RequestContext request)
at System.ServiceModel.Dispatcher.ChannelHandler.TryRetrievingInstanceContextCore(RequestContext request)
</p>
How can I fix it?
Thanks
You basically just need two separate endpoint address.
Change the config and give unique address, for example:
<endpoint address="DataExtractor" behaviorConfiguration="restBehavior" binding="webHttpBinding" contract="SysLap.Services.Web.DataExtractor.IServiceDataExtractor" />
<endpoint address="ScopesExtractor" behaviorConfiguration="restBehavior" binding="webHttpBinding" contract="SysLap.Services.Web.DataExtractor.IScopesExtract" />
When we use the WCF project template to create WCF service, normally there is only one service host in Service.svc(Markup).
<%# ServiceHost Language="C#" Debug="true" Service="WcfService3.Service1" CodeBehind="Service1.svc.cs" %>
It means that we could have multiple service contracts, but we merely can have one service(service implementation class).
Under this circumstance, hosting multiple service contracts in one project is valid.
public class Service1 : IService1,IService2
Back to your problem, the error mainly indicates that our services have the same relative address, this does not comply with the WCF addressing specification.
As Selim Yıldız said, we need two separate endpoint address.
<services>
<service name="WcfService3.Service1">
<endpoint address="a" binding="webHttpBinding" contract="WcfService3.IService1" behaviorConfiguration="rest"></endpoint>
<endpoint address="b" binding="webHttpBinding" contract="WcfService3.IService2" behaviorConfiguration="rest"></endpoint>
</service>
</services>
The service Url will be,
http://xxxx:xx/service1.svc/a/GetAllUsers
http://xxxx:xx/service1.svc/b/GetAllScopes
Feel free to let me know If there is anything I can help with.
I'm writing a multi-tenant WCF application. I've got one "general" service class that is responsible for executing some business logic. I'd like to configure WCF with Autofac in this way that each endpoint will receive different configuration params using custom configuration section e.g.:
<system.serviceModel>
<services>
<service name="MyApiService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:80000" />
</baseAddresses>
</host>
<endpoint name="Tenant1" address="tenant1" binding="basicHttpBinding" contract="IMyApiService" />
<endpoint name="Tenant2" address="tenant2" binding="basicHttpBinding" contract="IMyApiService" />
</service>
</services>
</system.serviceModel>
<apiConfigurationSection>
<service name="Tenant1" wcfServiceName="MyApiService" param1="value1" param2="value2" />
<service name="Tenant2" wcfServiceName="MyApiService" param1="value3" param2="value4" />
</apiConfigurationSection>
I'd like parameters param1 and param to be injected as a contex when matching service (by URL) is called.
Could you suggest me any solution how to do this?
I'm having trouble figuring out an issue with a WCF service that has appeared after I have implemented a "v2" contract to it to extend functionality. Everything builds fine but when I try to access the service in the browser I just get told that it cannot connect. When I try to add it as a service reference I get a similar message regarding connection issues. However, when I remove the extended contract's endpoint from the config file, and leave the previous "v1" version intact, it works fine.
Here is the "v1" contract:
namespace Company.Services.Ticketing.Retail.Contracts
{
[ServiceContract(Name = "OutletReportingContract_v1", Namespace = "https://enterprise.company.ie/Services/Retail")]
public interface IOutletReportingContract_v1
{
/* methods */
}
}
And here is the "v2" contract:
namespace Company.Services.Ticketing.Retail.Contracts
{
[ServiceContract(Name = "OutletReportingContract_v2", Namespace = "https://enterprise.company.ie/Services/Retail")]
public interface IOutletReportingContract_v2 : IOutletReportingContract_v1
{
/* methods */
}
}
Here are the endpoints in the Web.config:
<service name="Company.Services.Ticketing.Retail.OutletService" behaviorConfiguration="Public">
<endpoint address="1" binding="wsHttpBinding" bindingConfiguration="Standard" name="OutletReportingContract_v1"
contract="Company.Services.Ticketing.Retail.Contracts.IOutletReportingContract_v1" />
<endpoint address="2" binding="wsHttpBinding" bindingConfiguration="Standard" name="OutletReportingContract_v2"
contract="Company.Services.Ticketing.Retail.Contracts.IOutletReportingContract_v2" />
<endpoint address="mex" binding="mexHttpsBinding" name="IMetadataExchange" contract="IMetadataExchange" />
</service>
And here is the error message that appears in the event viewer:
WebHost failed to process a request.
Sender Information: System.ServiceModel.Activation.HostedHttpRequestAsyncResult/28075619
Exception: System.Web.HttpException (0x80004005): There was no channel actively listening at 'https://phil-pc.company.local/Services/Retail/OutletService.svc/_vti_bin/ListData.svc/$metadata'. This is often caused by an incorrect address URI. Ensure that the address to which the message is sent matches an address on which a service is listening. ---> System.ServiceModel.EndpointNotFoundException: There was no channel actively listening at 'https://phil-pc.company.local/Services/Retail/OutletService.svc/_vti_bin/ListData.svc/$metadata'. This is often caused by an incorrect address URI. Ensure that the address to which the message is sent matches an address on which a service is listening.
at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result)
Process Name: w3wp
Process ID: 8148
A bit stumped now and would appreciate any help :)
You need to separate your services declaration in web.config.
Assuming your implementation classes are named OutletService_v1 & OutletService_v2 you should end up with something like that:
<services>
<service name="Company.Services.Ticketing.Retail.OutletService_v1" behaviorConfiguration="Public">
<endpoint binding="wsHttpBinding" bindingConfiguration="Standard" contract="Company.Services.Ticketing.Retail.Contracts.IOutletReportingContract_v1" />
<endpoint address="mex" binding="mexHttpsBinding" name="IMetadataExchange" contract="IMetadataExchange" />
</service>
<service name="Company.Services.Ticketing.Retail.OutletService_v2" behaviorConfiguration="Public">
<endpoint binding="wsHttpBinding" bindingConfiguration="Standard" contract="Company.Services.Ticketing.Retail.Contracts.IOutletReportingContract_v2" />
<endpoint address="mex" binding="mexHttpsBinding" name="IMetadataExchange" contract="IMetadataExchange" />
</service>
</services>
My friend has the following app.config. He wants to get the value of address. how to do it?
<configuration>
<system.serviceModel>
...
<client>
<endpoint address="http://ldo:8080/LLService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ILLService" contract="LLServiceReference.ILLService"
name="WSHttpBinding_ILLService">
<identity>
<userPrincipalName value="ggldoe#mail.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
...
</configuration>
try this to Get first endpoint
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
ServiceModelSectionGroup serviceModelSectionGroup = ServiceModelSectionGroup.GetSectionGroup(configuration);
ClientSection clientSection = serviceModelSectionGroup.Client;
var el = clientSection.Endpoints[0];
return el.Address.ToString();
Take a look at the <system.serviceModel> documentation in MSDN.
You should:
Call the ServiceModelSectionGroup.GetSectionGroup method
Choose an endpoint from the serviceModelSectionGroup.Client.Endpoints collection. Presumably you want to look at a specific contract.
Look at that endpoint's Address property
I created a WCF service and exposed three endpoints which are basicHttpBinding, wsHttpBinding and webHttpBinding. This is a test service for my experiments with WCF. But, whenever I add service reference using the .svc file, I only get two (basic and ws) endpoints. There doesn't seem to be a third (webHttpBidning) endpoint being exposed for some reason.
To reproduce this issue, create a WCF application project, delete the Service1 service, add new item > WCF service named TestService, and change the config file to the following :
<system.serviceModel>
<services>
<service name="WcfTestService.TestService" behaviorConfiguration="TestServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost/WcfTestService/TestService.svc"/>
</baseAddresses>
</host>
<endpoint address="basic"
binding="basicHttpBinding"
contract="WcfTestService.ITestService" />
<endpoint address="ws"
binding="wsHttpBinding"
contract="WcfTestService.ITestService" />
<endpoint address="web"
binding="webHttpBinding"
contract="WcfTestService.ITestService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TestServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
Here is the code for ITestService.cs:
[ServiceContract]
public interface ITestService
{
[OperationContract]
[WebInvoke]
Boolean ValidateUser(User user);
}
[DataContract]
public class User
{
[DataMember(Name = "Name")]
public String UserName { get; set; }
[DataMember]
public String Password { get; set; }
}
and for TestService.svc
public class TestService : ITestService
{
public bool ValidateUser(User user)
{
if (user.UserName == "User" && user.Password == "123")
{
return true;
}
return false;
}
}
I tried different combination of WebInvoke parameters and WebGet parameters, but failed.
Can anyone tell me why the third endpoint is not showing up in the WSDL file?
#decyclone: I have successfully exposed webHttpBindings without any issue. But I found some interesting thing when it get exposed and when it not!
I can see web binding getting exposed in Wcf Test Client.
Here are my configurations
<services>
<service behaviorConfiguration="TestWeb.Service2Behavior" name="TestWeb.Service2">
<endpoint address="" binding="wsHttpBinding" contract="TestWeb.Service2">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="web" binding="webHttpBinding" contract="TestWeb.Service2">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
Point to note here is, its working fine using VS2008 with Framework 3.5, VS2010 with Framework 3.5, when I use VS2010 and Framework 4.0 then I can't see WebHttpBinding getting exposed in WCF Test Client, however I can use that binidng to do http post in all cases.
I assume that in Framework 4.0 its not visible by default, even I try enable endpointDiscovery but still no luck!
I have covered this behaviour in my post
Your "web" endpoint will be exposed as a JSON endpoint. It is not compatible with WSDL.
WebHttpBinding is in System.ServiceModel.Web. If you are using vs2010, go to properties of your project, check target framework. By default it points to .Net Framework 4 Client Profile. It should point to .Net Framework 4, then you can find the System.ServiceModel.Web when you will go to Add reference
#decyclone: One way that a javascript client can learn the available methods on a webHttpBinding is to download a WCF javascript proxy with HTML script tags pointing to your endpoint followed by "/js": <script src="http://localhost/WcfTestService/TestService.svc/web/js"></script>