In my ASP.NET WebForms project I have a reference to the WCF services library project, which contains different WCF services for each business object. The services are hosted in IIS and it's possible to get WSDL via routes I defined in the Global.asax: one WSDL via one route for each service.
What I really need - some ability to choose services what I want to provide for different customers and generate a SINGLE WSDL for the chosen services set.
Yes its possible to configure WCF routing service and get WSDL files form individual service behind it.
Step 1 - Set HttpGetEnabled set to true and configure MEX Endpoint in all WCF Service those are behind your router service
<service behaviorConfiguration="routingBehv" name="System.ServiceModel.Routing.RoutingService">
<host>
<baseAddresses>
<add baseAddress="http://localhost/WcfRoutingService/RoutingService.svc"/>
</baseAddresses>
</host>
<endpoint address="http://localhost/WcfRoutingService/RoutingService.svc" binding="mexHttpBinding" name="mexEndpoint" contract="System.ServiceModel.Routing.IRequestReplyRouter"/>
</service>
Step 2- Configure Routing Service
Add Endpoint
<endpoint address="" binding="mexHttpBinding" name="mexEndpoint" contract="System.ServiceModel.Routing.IRequestReplyRouter"/>
Add service behaviour
<behaviors>
<serviceBehaviors>
<behavior>
<routing routeOnHeadersOnly="false" filterTableName="routingTable" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Client Endpoint address should specify the "MEX" endpoint address
<client>
<endpoint address="http://localhost/PremiumWcfService/PremiumWCFService.svc/mex" binding="mexHttpBinding" contract="*" name="PremiumServiceMex"/>
<endpoint address="http://localhost/StandardWCFService/StandardWCFService.svc/mex" binding="mexHttpBinding" contract="*" name="StandardServiceMex"/>
</client>
Specify the routing table
<routing>
<filters>
<filter name="StandardServiceMexFilter" filterType="EndpointAddress" filterData="http://tempuri.org/WcfRoutingService/RoutingService.svc/StandardService" />
<filter name="PremiumServiceMexFilter" filterType="EndpointAddress" filterData="http://tempuri.org/WcfRoutingService/RoutingService.svc/sPreminuService" />
</filters>
<filterTables>
<filterTable name="routingTable">
<add filterName="StandardServiceMexFilter" endpointName="StandardServiceMex"/>
<add filterName="PremiumServiceMexFilter" endpointName="PremiumServiceMex"/>
</filterTable>
</filterTables>
</routing>
You are all done.
You can directly access the WSDL file of your services by below URLS individually :
http://localhost/WcfRoutingService/RoutingService.svc/StandardService
http://localhost/WcfRoutingService/RoutingService.svc/PremiumService
the problem in your solution is : you give to your clients a WSDL with the address of your web service PremiumWCFService and StandardService , and the clients (WCF) can use that directly without check and can call your web sevices without call routing service.
Related
I created a RESFTful WCF web service and i installed it in IIS as a new web application. The WCF has some actions like: Login, getEmployees ...etc. and it works fine when i publish and run it from vs, so i can reach from browser links like:
http://myserver/service.svc
http://myserver/service.svc?wsdl
http://myserver/Login?user=sample&password=paswd
http://myserver/getEmployees?name=dada
and with the action links i get the exact needed data as a response.
however it works only when i run the web service from vs, but when i try to reach the links from browser and the web service is NOT running in VS i can reach only links like:
http://myserver/service.svc
http://myserver/service.svc?wsdl
but not the operational links like:
http://myserver/Login?user=sample&password=paswd
http://myserver/getEmployees?name=dada
Endpoints configurations:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings/>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<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="AXPAYROLL.PayrollActions" behaviorConfiguration="serviceBehavior">
<endpoint address="http://myserver/" behaviorConfiguration="RESTFriendly" binding="webHttpBinding" contract="AXPAYROLL.IPayrollActions">
<identity>
<dns value="myserver" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://myserver/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="RESTFriendly">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="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" />
<serviceAuthorization serviceAuthorizationManagerType="AXPAYROLL.DataContractLayer.DistributorValidator, AXPAYROLL" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I also created a console host application where everything worked just fine like from vs, so the problem in IIS for sure may be in permissions...
I am new in WCF but i believe that it can't be the right way to run vs always to get the wcf deployed!!! i also want to install the wcf on a productive server where no vs is installed, i know that the self hosting could be achieved with the console application but this is again not what i want, i want it torun over normal iis,any idea what is the problem? did i miss something?
When the WCF service on IIS, any base address specified in the <baseAddresses> will be ignored and the base address will be the URL to the .svc file.
The address attribute in the endpoint element is a relative address and could be like address="rest".
So in IIS, the url will be http://myserver/service.svc/rest/getEmployees?name=dada
Update:
To remove svc extension, have a look at this question
From my silverlight 4.0 application. I can access the WCF File easily but when moved to https, I can't access the WCF Service. The error details are following:
An unknown error occurred. Please contact your system Administrator for more information.
An exception occurred during the operation, making the result invalid. Check InnerException for exception details.
at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at FileSearch.SearchServices.GetTypeofFileDetailedCompletedEventArgs.get_Result()
at FileSearch.Home.<SearchButton_Click>b__0(Object s, GetTypeofFileDetailedCompletedEventArgs ea)
at FileSearch.SearchServices.SearchServiceClient.OnGetTypeofFileDetailedCompleted(Object state)
I have seen different posts regarding this issue, but nothing is pointing me in a proper direction.
Here are the details regarding my web.config file for the web application that hosts the silverlight application as well as the WCF Service.
<services>
<service name="FileSearch.Web.Services.SearchService">
<endpoint address="" binding="customBinding" bindingConfiguration="FileSearch.Web.Services.SearchService.customBinding0" contract="FileSearch.Web.Services.SearchService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
and here is the servicerefernce.clientconfig file:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_SearchService">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="../Services/SearchService.svc"
binding="customBinding" bindingConfiguration="CustomBinding_SearchService"
contract="SearchServices.SearchService" name="CustomBinding_SearchService" />
</client>
</system.serviceModel>
</configuration>
UPDATE:
I've received answers to run the service in the https mode only. I want to run the service in both http and https modes.
any ideas regarding this ?
Specify two endpoints one with secured transport and one without it.
try adding
<security mode="Transport" />
in you service config file. this should be nested inside the binding node.
Check out the security mode configuration section in this article.
For supporting Https scheme, you'd need to change transport to <httpsTransport>. I see you're using <httpTransport>.
I've tried this on two machines and can't figure it out. I've followed the instructions here (http://msdn.microsoft.com/en-us/library/ms731053.aspx) and ensured that the TCP listener service is running. However, next to the site application, I see "Unknown (net.tcp)" as the status.
For enabled protocols in IIS, they are listed as "http,net.tcp". My binding for net.tcp is "808:*" and the app pool is .NET 4.0 integrated. Let me know what information I can provide.
Also, when trying to connect, it says it cannot connect to the mex endpoint. My service endpoint code is below. Any help is appreciated. Thanks.
<system.serviceModel>
<services>
<service name="Sandbox.ClientSideWCF.Service">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:808/service.svc" />
</baseAddresses>
</host>
<endpoint name="TcpEndpoint" address="" contract="Sandbox.ClientSideWCF.IService" binding="netTcpBinding" />
<endpoint name="MetaInfo" contract="IMetadataExchange" binding="netTcpBinding" address="mex" />
</service>
</services>
....
</system.ServiceModel>
The < baseAddresses > element is for self-hosted services. See here:
http://msdn.microsoft.com/en-us/library/ms788995.aspx
Try removing it. Also see this link How to: Host a WCF Service in WAS:
http://msdn.microsoft.com/en-us/library/ms733109.aspx
I think I figured it out. The problem was that I didn't include a service behavior. I added an empty behavior and it worked. I didn't know this was required.
Despite all of my efforts, I have not been able to get my simple WCF service hosted on IIS with SSL.
We are using windows server 2k3 with IIS 6.0 and we have up to .NET 4.0 installed on the server (web site is configured for 4.0)
If i go to http//.../rptService.svc url, I get the .svc page with the code blocks and ?wsdl url
on the other hand, if i go to https//.../rptService.svc I get a "Resource not found" 404 error. (colons on urls are removed b/c of spam prevention)
The web site has a working SSL certificate enabled for it.
My relevant web.config file is as follows:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="rptBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="wcfApp.rptServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpsGetEnabled="false" httpGetEnabled="true" />
<serviceTimeouts/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="wcfApp.rptServiceBehavior"
name="wcfApp.rptService">
<endpoint binding="wsHttpBinding" bindingConfiguration="rptBinding" contract="wcfApp.rptService"
address="">
</endpoint>
<endpoint name="MetadataBinding" address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
I have tried just about 100 different ways to write the web.config file from 150 different blog/web posts with similar situations, and have not gotten anything to work thus far.
My end goal is to get this wcf service hosted accepting a username/password token with a custom user name validator, but right now I can't even get it working with SSL!
Application is being built in VS 2010.
Please let me know if there is any more information that I can provide.
Any help is appreciated!
I've setup up a WCF web service to handle requests from a Silverlight application. That service has Windows authentication set up which works well with the following endpoint configuration
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Test.Service.ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="customBinding0">
<binaryMessageEncoding/>
<httpTransport authenticationScheme="Negotiate"/>
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service behaviorConfiguration="Test.Service.ServiceBehavior" name="Test.Service.Service">
<endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="Test.Service.Service"/>
<endpoint address="mex" binding="customBinding" bindingConfiguration="customBinding0" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
The service also has the following code in the constructor which authenticates to a TFS server
teamFoundationServer = TeamFoundationServerFactory.GetServer(tfsServer);
teamFoundationServer.EnsureAuthenticated();
workItemStore = (WorkItemStore)teamFoundationServer.GetService(typeof(WorkItemStore));
Then I have a Silverlight application that uses this web service and contains the following code to access it
proxy = new ServiceClient("Service");
Lastly there is a host web site that only contains the .xap silverlight file. That site has also Windows authentication configured.
Both the service and the host are running in IIS.
The problem I'm having is that when the service authenticates with TFS I always get an exception
Microsoft.TeamFoundation.TeamFoundationServerUnauthorizedException: TF30063: You are not authorized to access
Since the service and the host are windows authenticated then the Silverlight application is most likely causing me problems. After googling Silverlight and authentication it seems like there is some issue realated for Silverlight to forwarding the credential from the host to the service. Has someone been able to accomplish this task ?
To provide further info then I've been able to get the current users username by doing
OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.AuthenticationType
But that returns a WindowsIdentity which is not compatible with ICredential which the TFS API requires :(