I'm new to WCF and I'm trying to use a contract defined externally in my code. The issue is that my code, as well as the external code have 2 conflicts with the same class name within the same namespace. I added the external nuget, and specified it's alias in References in Visual Studio to resolve the conflicts. In the C# file, I'm able to use it with extern alias, as below -
extern alias X;
using X.IT.Contracts;
However, the contract also has to be used in web.config. The below two ways are not working -
<endpoint address="net.pipe://localhost/XYZ.svc" binding="netNamedPipeBinding" contract="IT.Contracts.Service.IXService" behaviorConfiguration="InterceptorBehavior" />
<endpoint address="net.pipe://localhost/XYZ.svc" binding="netNamedPipeBinding" contract="X.IT.Contracts.Service.IXService" behaviorConfiguration="InterceptorBehavior" />
Is there a way to specify the alias for an assembly in the web.config file?
Related
I am implementing this from a WCF book. I read the following from the book:
The website config file (web.config) typically lists the types you want to expose as services. You need to use fully qualified type names, including the assembly name if the service type comes from an unreferenced assembly:
< system.serviceModel >
< services >
< service name = "MyNamespace.MyService" > ... </ service >
</ services >
</ system.serviceModel >
Using this, I have written the following in web.config in my Service project:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="MyService.svc" service="Service"/>
<add relativeAddress="MyAssemblyService.svc" service="WcfServiceLibrary1.Service1"/>
</serviceActivations>
</serviceHostingEnvironment>
<services>
<service name="Service">
</service>
<service name="WcfServiceLibrary1.Service1">
</service>
</services>
Here, if I reference the Service Assembly in my WCF Service project, I can access the service, but if I leave out the reference to Service Assembly, I get the following error:
The type 'WcfServiceLibrary1.Service1', provided as the Service
attribute value in the ServiceHost directive, or provided in the
configuration element
system.serviceModel/serviceHostingEnvironment/serviceActivations could
not be found.
I have searched a lot to find, how to specify the full qualified service name in the "name" attribute including the assembly, but it seems either I am not using the right search keywords or we can't specify the assembly name in "name" attribute.
Can we specify the assembly name inside the "name" attribute?
Hi you need the fully qualified name, and the assembly in the GAC
Here is a hint how to get the fully qualified name:
https://msdn.microsoft.com/en-us/library/2exyydhb.aspx
Here is the tutorial for installing the assembly in the GAC:
http://net-informations.com/faq/framework/add-remove-assembly
I inherited some code which included a service reference. I realized that the server the reference pointed was removed. I still have the code which included an .svc file. I guess that must be a WCF kind of a service, and I need to restore it on another server, but I have no idea how to do that.
As I said, the code includes an svc file, and also Web.config, Web.Debug.config, Web.Release.config, a project file, and some source files.
Updated question with web.config
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" >
<serviceActivations>
<add relativeAddress="ExcelConversionService.svc"
service="MyDomain.FileServices.ExcelConversionService"/>
</serviceActivations>
</serviceHostingEnvironment>
You can host this service in IIS. please look at the following MSDN references
http://msdn.microsoft.com/en-us/library/aa751792.aspx
http://msdn.microsoft.com/en-us/library/ms734710.aspx
A more hands-on example is available at
http://www.codeproject.com/Articles/150066/Create-Host-Self-Hosting-IIS-hosting-and-Consume-W
I am trying to figure out how to provide endpoints etc to a WF Service that I created (MyFoo.xamlx). Typically when you create a Service you need to have the Service name="" reflect the type of service you've created? ie by filling out something like this:
<Service name="MyNameSpace.Foo" behaviorConfiguration="myFooBehaviorConfig">
This works in a typical .svc scenario and I can get that working fine. Only how does one map this concept across to a .xamlx service? In that if I have Foo.xamlx putting that inside the Service name doesn't work - or doesn't appear to work (as in no metadata is enabled).
If i then remove the behaviorConfiguration attribute from the Service and also remove the myFooBehaviorConfig from the <behavior/> tag - in that it essentially then takes on more of a global setting for the web config - boom! I can see the .xamlx exposed methods/operations?
<serviceBehaviors>
<behavior name="foo" >
vs
<serviceBehaviors>
<behavior >
At first this is great, no effort required but at the same time I don't want devs to access HTTP endpoints or netpipe for that matter. I only want them to come in through net.tcp port I specify. In order to do that I need to match the <Service name=""/> to the xamlx somehow?
I've also tried using the trick of creating an empty .svc file and then pointing to the xamlx that way (so that the devs always assume its a .svc and not a .xamlx)
<%# ServiceHost Language="C#" Debug="true" Service="ActivityHubService.xamlx" Factory="System.ServiceModel.Activities.Activation.WorkflowServiceHostFactory" %>
Again, if I remove naming the behavior etc this also works via foo.svc ..but i just can't seem to crack the whole matching a <service> with a freakin xamlx!! :) hehe.
Frustrating..
Anyone an expert in this space?
I'm gonna give this one to GuerreroTook as although the answer he gave was partially in the same area of right it did however spark a moment of "yeah maybe its that simple.." thinking..
The solution was this:
<services>
<service name="ActivityHubService" behaviorConfiguration="foo">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="netTCPStreamedBinding" contract="IService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://synapse.hub.security:669/SynapseHubSecurity/ActivityHubService" />
</baseAddresses>
</host>
</service>
</services>
Then inside a service i called PingService.svc I put this:
<%# ServiceHost Language="C#" Debug="true" Service="ActivityHubService.xamlx" Factory="System.ServiceModel.Activities.Activation.WorkflowServiceHostFactory" %>
That seemed to have done the trick!! :)
Not sure why but i swore I did this like 3x and it failed..but...i am also in need of sleep..
Hopefully this will help others in the same jam down the track.
Based on what you ask, I understand that you need to expose a WF Workflow as a WCF service and you want client to call directly WF through WCF infrastructure, is that right?
The problem you facing is that you need to provide the full qualified name of the class in order to the factory to find and activated your WF workflow. If you have a typical WP project inside VisualStudio the Full Qualified Name is the name of the project + the class name, try with this.
When you build your workflow xaml file the compile will generate a class that hold and the code and logic, and following the same behavior of the xaml (WPF and Silverlight) compiler the name of the class will be the same of the file (.xamlx)
I have a set of Service Contracts which split up my service interface into chunks of related functionality. I am currently implementing all contracts using a single service class (may want to split these later but for now the single service class suffices).
I am trying to use configure the endpoints using a config file (as opposed to via code). The problem is I get a ServiceActivationException because the two endpoints (one for each service contract) are trying to listen on the same uri. The exception details say that to achieve this the two endpoints must share the binding object, which makes sense but I can't figure out how to do this via config (I haven't tried doing this via code as I am hosting in IIS but I can imagine it being a simple exercise to configure in code).
The following is the config I am currently using (this is still dev so I'm not currently worried about security concerns etc. that some of these settings may expose):
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="CDC.WebPortal.MidTier.MidTierAccessService"
behaviorConfiguration="MidTierServiceBehaviour" >
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration="RestBindingConfiguration"
contract="****************************.IProductService" />
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration="RestBindingConfiguration"
contract="****************************.ICategoryService" />
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="RestBindingConfiguration"
maxReceivedMessageSize="104857600">
<readerQuotas maxStringContentLength="104857600"/>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MidTierServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
So my question is how do I share this binding between the two endpoints?
Comments in this SO question suggest I may not be able to do this, but I don't beleive that is correct.
UPDATE 1 According to this MS publication what I'm doing should be ok...
UPDATE2 Here is the svc file content if it helps:
<%# ServiceHost Language="VB" Debug="true"
Service="*********************.MidTierAccessService"
Factory="Microsoft.ServiceModel.Web.WebServiceHost2Factory" %>
UPDATE 3 Here is the exception detail:
A binding instance has already been associated to listen URI '********************'. 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.
UPDATE 4 Ok I missed this before, stating "You will need to use relative addresses when exposing more than one endpoint for a particular .svc service". The cause of this is something to do with the IIS virtual directory determining the base address of the service, can anyone explain this in a little more detail, i.e. why IIS needs relative addressing for each contract.
To my knowledge, and I have been doing extensive work with WCF in the last month, you can not share the same exact URI for more than one endpoint. In WCF, a "service" is not defined by the implementation of a contract, but by the contract itself (which also follows WSDL and standard SOA practices.) Endpoints allow you to expose a single service via multiple protocols (and therefor different addresses), but you can not share different services on the same exact address. Logically that wouldn't work.
Assume the following scenario (which is what you are trying to accomplish):
IProductService exposed # http://localhost/service
ICategoryService exposed # http://localhost/service
IMetadataExchange exposed # http://localhost/service/mex
It is easy enough to access the MEX endpoint...it has a unique URI. However, how do you access either of IProductService or ICategoryService? There is nothing that allows you to differentiate the two other than a URI. WCF has nothing that will allow it to route between messages that are supposed to go to IProductservice, and those that are supposed to go to ICategoryService. Since both use the same URI, you do indeed have a conflict. Every service CONTRACT must be exposed via a unique URI. Every endpoint that utilizes the same exact binding must use a distinct address.
There is a way to achieve what you need. The problem is message routing. WCF does not natively support message routing OOB, however it does provide the ability to implement your own message router. (Or, if you are willing to use beta tech, .NET 4.0 comes with a message router out of the box, based on the articles linked below, but with improved configurability.) Michele Bustamante, a veritable sorceress of WCF, has provided a complete implementation and article describing message routing at the following links:
http://msdn.microsoft.com/en-us/magazine/cc500646.aspx
http://msdn.microsoft.com/en-us/magazine/cc546553.aspx
The general idea is that you set up a single service that listens on a single URI. This service uses wildcard dispatch to a single service operation, which then determines which unique URI to route each message to. You can make the determination any way you wish, however the simplest is via the request Action, assuming each action on your two interfaces, IProductService and ICategoryService, are globally unique. You will end up with more services, however...the router itself is a distinct WCF service that would need to be hosted just like any other.
How can I correctly serve WSDL of a WCF webservice located in a private LAN from behind a reverse proxy listening on public IP?
I have an Apache webserver configured in reverse proxy mode which listens for requests on a public IP address and serves them from the internal IIS host. WCF webservice generates WSDL using the FQDN address of the LAN host which, of course, cannot be read by an internet web service client.
Is there any setting that can be configured in wcf application's web.config or in IIS in order to customize the WSDL generated containing host address and put public address instead?
Add the following attribute to your service class:
<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)>
This allows the service to be addressed by the client as https://... but the service can still be hosted on http://.....
See my answer on How to specify AddressFilterMode.Any declaratively for how to create an extension to allow AddressFilterMode.Any to be specified through configuration without requiring code attributes.
In the web.config of the service host, the endpoint element must have an absolute URL in the address attribute that is the public URL that will be used by the client. In the same endpoint element, set the listenUri attribute to the absolute URL on which the service host is listening.
The way I determine what the default absolute URI the host is listening on is to add a service reference in a client application which points the the physical server where the service is hosted. The web.config of the client will have an address for the service. I then copy that into the listenUri attribute in the hosts web.config.
In your service behavior configuration, add the element serviceMetaData with attribute httpGetEnabled=true
So you'll have something like this:
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<!-- ... -->
<services>
<service name="NamespaceQualifiedServiceClass" behavior="myBehavior" >
<endpoint listenUri="http://www.servicehost.com"
address="https://www.sslloadbalancer.com"
binding="someBinding"
contract="IMyServiceInterface" ... />
</service>
</services>
I am not sure if this works with message security or transport security. For this particular application, the credentials were passed as part of the DataContract so we had basicHttpBinding > security > mode=none. Since the transport is secure (to the ssl load balancer) there were no security issues.
It is also possible in to leave the listenUri attribute blank, however it must be present.
Unfortunately, there is a bug in WCF where the the base address of imported schemas in the WSDL have the listenUri base address rather than the public base address (the one configured using the address attribute of the endpoint). To work around that issue, you need to create an IWsdlExportExtension implementation which brings the imported schemas into the WSDL document directly and removes the imports.
An example of this is provided in this article on Inline XSD in WSDL with WCF. Additionally you can have the example class inherit from BehaviorExtensionElement and complete the two new methods with:
Public Overrides ReadOnly Property BehaviorType() As System.Type
Get
Return GetType(InlineXsdInWsdlBehavior)
End Get
End Property
Protected Overrides Function CreateBehavior() As Object
Return New InlineXsdInWsdlBehavior()
End Function
This will allow you to add an extension behavior in the .config file and add the behavior using configuration rather than having to create a service factory.
Under the system.servicemodel configuration element add:
<behaviors>
<endpointBehaviors>
<behavior name="SSLLoadBalancerBehavior">
<flattenXsdImports/>
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<!--The full assembly name must be specified in the type attribute as of WCF 3.5sp1-->
<add name="flattenXsdImports" type="Org.ServiceModel.Description.FlattenXsdImportsEndpointBehavior, Org.ServiceModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
And then reference the new endpoint behavior in your endpoint configuration using the behaviorConfiguration attribute
<endpoint address="" binding="basicHttpBinding" contract="WCFWsdlFlatten.IService1" behaviorConfiguration="SSLLoadBalancerBehavior">
I'm having similar issues, one of which was the resolution of public and server addresses. This solved that issue although I still have a couple authentication problems.
See: How to change HostName in WSDL for an IIS-hosted service? by Wenlong Dong
archive
See: Service Station WCF Addressing In Depth by Aaron Skonnard
archive link