I am using Dynamic IIS Hosting (http://blog.micic.ch/net/dynamic-iis-hosted-wcf-service) with http binding. How can I use tcpbinding with dynamic IIS hosting.
Thanks
If you are experiencing problems with registration VirtualPathProvider on start up using non-HTTP activation, you should put class with any name to App_Code folder. This class must have public static void AppInitialize() method, where you can register VirtualPathProvider.
namespace YourHostNameSpace.App_Code
{
public class NonHttpActivation
{
public static void AppInitialize()
{
//do start up stuff here
}
}
}
By the way, WCF 4 provides file-less functionality out of the box on top WCF 4 Routing.
Related
I have a fairly simple design question about interaction between a self hosted WCF Service and other business classes.
Here is the WCF service contract :
/// <summary>
/// Represent requests on hardware components made by a client to the controler service
/// </summary>
[ServiceContract(CallbackContract = typeof(IHardwareServiceCallback))]
public interface IHardwareService
{
[OperationContract(IsOneWay = true)]
void OpenLeftDrawer();
[OperationContract(IsOneWay = true)]
void OpenRightDrawer();
}
The service implementation
public class HardwareService : IHardwareService
{
public void OpenLeftDrawer()
{
}
public void OpenRightDrawer()
{
}
}
A class which purpose is to handle the business logic regarding client calls on the server
class DrawerRequestManager
{
// Server side Business logic to handle OpenDrawer requests from client
}
Hosting scenario
Uri adrbase = new Uri(srvConfig.Address);
var host = new ServiceHost(typeof(HardwareService), adrbase);
host.AddServiceEndpoint(typeof(IHardwareService), srvConfig.Binding, srvConfig.Address);
host.Open();
Since this is the host that is managing the service instance lifetime, what is the proper way to handle the link between the service instance and business logic classes (DrawerRequestManager for exemple).
I'm using IOC container but i'm also interested in the response when not using IOC container.
Thanks in advance !
WCF uses parameterless constructor to create service objects, but there is a way to alter that. You need to implement your own instance provider.
You can inject your instance provider via ServiceHostFactory: see here.
Alternatively you can inject instance provider by using custom attribute for your service: see here.
Either way gives you full control of how services instances are created. You can use IOC there or just call constructor manually passing any parameters you want (e.g. reference to DrawerRequestManager instance).
I have a WCF service that is defined in a module. When we try to call this service from a non-default tenant, the content manager always references our default tenants settings. In debugging, inside of OrchardServiceHostFactory,
I notice that it ends up getting the settings for the default tenant because the base address that is passed into the CreateServiceHost method is always our default tenants uri.
Given that I am not wholly familiar with WCF, is there a configuration option that I am missing that is causing the WCF service to be created with the default tenants address, instead of the non-default tenant?
Relevant code:
private static readonly Route _SITEMAP_SERVICE_ROUTE = new ServiceRoute("api/SitemapService", new OrchardServiceHostFactory(), typeof(ISitemapService))
{
DataTokens = new RouteValueDictionary
{
{
"area", "Project.Localization"
}
}
};
public interface ISitemapService : IOrchardSitemapService, IDependency
{
}
[ServiceContract]
public interface IOrchardSitemapService
{
[OperationContract]
int GetNavigableContentCount();
[OperationContract]
List<SitemapEntry> GetNavigableContent();
}
I was able to fix this by adding an additional site to IIS that pointed to the same file system location, and used the same application pool. This new site then references the non-default's tenant, and the service will now be created with the correct base address.
Is there Any way of hosting WCF service on Linux.
I read about wine but i didn't see any example of hosting WCF service with it.
P.S : I have tried mono and mod_mono but to no avail.
You can host it in a stand-alone console application like so:
using System;
using System.ServiceModel;
using Service;
namespace Host
{
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("WCF Host!");
var binding = new BasicHttpBinding ();
var address = new Uri ("http://localhost:8080");
var host = new ServiceHost (typeof(GreeterWcfService));
host.AddServiceEndpoint (
typeof(IGreeterWcfService), binding, address);
host.Open ();
Console.WriteLine ("Type [Enter] to stop...");
Console.ReadLine ();
host.Close ();
}
}
}
Where GreeterWcfService is the WCF service class itself and IGreeterWcfService is the service contract.
Full working example solution in GitHub - with separate projects for the service, the hosting and a client. Check it out.
Its possible but you should refer to this link for understanding current state and known issues - http://www.mono-project.com/docs/web/wcf/. It's limited now. For eg. if you wish to use WSHttpBinding its not supported currently.
I have a wcf project running on IIS in a server that is not reachable from clients on the internet.
second project is the website that is open to the internet written in MVC c#4 razor engine.
I work a lot on just passing data from api controller to service client and back .
Is there a way to generate the code ?
let's say the code in my wcf service is on server unreachable to Internet is :
[ServiceContract]
public interface IAlertsService
{
[OperationContract]
void ApproveAlert(int ID);
[OperationContract]
bool IsAdditionalPackageRequired(int AlertID);
[OperationContract]
bool RemoveAlert(int ID);
//ApproveAllAlerts
[OperationContract]
bool ApproveAllAlerts(int[] ID);
}
and I did service reference from website mvc4, and want to make controller api :
public class AlertsController : ApiController
{
//here all methods to invoke wcf ...
}
is there a way to generate ApiControllers code from the service reference ?
I tried to minimize writing of code for WCF CRUD part of big project with use of generics and castle WCF facility.
I have WCF service contract:
[ServiceContract]
public interface IResourceService : ICRUDService<DTOResource>
{
[OperationContract]
DTOResource Get(long id);
}
and generic interface
public interface ICRUDService<T> where T is IDTO
{
T Get(long id);
}
also generic MVC controller (1 controller for all basic crud for dtos and services)
public class CRUDController<T> : Controller where T is IDTO
{
readonly ICRUDService<T> service;
public CRUDController(ICRUDService<T> service)
{
this.service = service;
}
}
On the client side i register WCF client in Windsor Container
Component
.For<IResourceService , ICRUDService<DTOResource>>()
.AsWcfClient(... standard stuff... )
Everythig is working fine, components and services registered, controller created properly,
service
readonly ICRUDService<T> service;
in controller is of type
Castle.Proxies.IResourceService
But when i try to use service in controller i have error
Method Get is not supported on this proxy, this can happen if the method is
not marked with OperationContractAttribute or if the interface type is not
marked with ServiceContractAttribute.
When in controller i hardcode cast
((IResourceService)service).Get(id);
all is running properly, so i believe this problem is solvable.
I've also tried to use Forward (with same result) :
Component
.For<IActionTypeService>
.Forward<ICRUDService<DTOResource>>().AsWcfClient(...
How to make it work?
In the end i had to use 'Channel Factory' on client side.
I was able to use Windsor WCF Facility on server side to register generic contract :
[ServiceContract]
public interface ICRUDService<I>
{
[OperationContract]
I Get(int id);
}
with generic implementation
public class CRUDService<I, IEntity> : ServiceBase, ICRUDService<I>
{
public I Get(int id)
{
...
}
in standard way (for multiple types)
private void InstallExample<I, IEntity>(IWindsorContainer container)
{
container.Register(
Component
.For<ICRUDService<I>>()
.ImplementedBy(CRUDService<I, IEntity>)
.Named("somename")
.AsWcfService(
new DefaultServiceModel()
.Hosted()
.PublishMetadata(x => x.EnableHttpGet())
.AddEndpoints(WcfEndpoint
.BoundTo(new BasicHttpBinding())
.At("someAddress")
)
)
.LifeStyle.PerWcfOperation();
}
with fileless activation in web.config
<add factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" service="ClientService" relativeAddress="./ClientService.svc" />
On server side it works perfectly. Sadly on client side i didn't found working solution for WCFFacility and i had to use ChannelFactory (which is working perfectly)
ChannelFactory<ICRUDService<I>> factory = new ChannelFactory<ICRUDService<I>>(someBinding, someEndpoint);
For the rest (standard non generic services i'm using WCF Facility without any problems.
I think you need to put the ServiceContract attribute on ICrudService<>, add the OperationContract to the method there and remove the duplicate declaration of Get() from IResourceService.