apicontroller facade for wcf - wcf

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 ?

Related

Server Side WCF Service : How to reference/interact with other server components

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).

Castle WCF Facility, Use of generic interface for non generic contract

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.

WCF: how to choose which type an interface will be serialize into?

When using WCF,
how can you choose which type an interface will be serialized into?
for example, the CarA type is used in the server, and they are sent to client over WCF as ICars, and the client should receive them as CarBs.
public interface ICar
{
int Size { get; set; }
int Price { get; set; }
}
public class CarA : ICar
{
//ICar implementations...
}
public class CarB : ICar
{
//ICar implementations...
}
[ServiceContract]
public interface ICarManager
{
[OperationContract]
ICar GetMyCar(int userID);
}
"which type an interface will be serialized into" - this makes zero sense. If you send CarA's to your client the client will receive CarA's.
I think you may be asking about how to tell WCF that your service contract contains types which are derived from another type. To do this you can use ServiceKnownTypeAttribute.
UPDATE
If you want to return a type of ICar in your service operation you need to specify the concrete types which will be available on your endpoint. You do this by using the ServiceKnownTypeAttribute like so:
[ServiceKnownType(typeof(CarA))]
[ServiceKnownType(typeof(CarB))]
[ServiceContract]
public interface ICarManager
{
[OperationContract]
ICar GetMyCar(int userID);
}
You could look at customize reply message by implement custom extension using IDispatchMessageFormatter
try this link if help you
IDispatchMessageFormatter – How to customize reply Messages on the server side
From Your server side you can only expose unique endpoint so you will expose only one endpoint as ICar and then you will choose which implementation of ICar you want to host via ServiceHost ,it can be CarA or CarB.
Now on client side you will just have a only interface as ICar and you should not be confused with which type should be serialized using your interface Icar. You will be only calling server side to get the service not the implementation.
More on ServiceHost
Use the ServiceHost class to configure and expose a service for use by
client applications when you are not using Internet Information
Services (IIS) or Windows Activation Services (WAS) to expose a
service. Both IIS and WAS interact with a ServiceHost object on your
behalf

How should I consume a WCF service using MVC3

I am writing a fairly simple MVC3 application that allows a user to retrieve and modify some configuration data held by a WCF service. The configuration data will not change very often but needs to be maintainable by the user.
Once the user is happy with the configuration, they will launch some processing from the UI or by the scheduled execution of a VB script.
I'm fairly new to WCF and even newer to MVC3 but I'd like to make all the comms to and from the service RESTful. Is this a good thing to do?
I'd been planning to perform the service communications from the MVC controller. This would make a HTTP Get request to retrieve the current configuration and a HTTP Post to apply the modified configuration. I'd also use a Get request to launch the processing.
Could anyone provide an example (or point me in the direction) of how I should be doing this?
Please follow the below links for some sample code to build a RESTful WCF Service and the how the client would access the service.
Link to create a RESTful service: here
Link to create a .NET client that consumes the RESTful service : here
Hope the information helps you out.
If you are the owner of web service, you can directly reference implementation of service in your mvc project and use it without web reference. You can write some like this:
// example of ws
public class Service1 : IService1
{
public string GetData( int value )
{
return string.Format( "You entered: {0}", value );
}
public CompositeType GetDataUsingDataContract( CompositeType composite )
{
if( composite == null )
{
throw new ArgumentNullException( "composite" );
}
if( composite.BoolValue )
{
composite.StringValue += "Suffix";
}
return composite;
}
}
// example of mvc action
public class HomeController : Controller
{
public ActionResult Index()
{
IService1 service = new Service1();
service.GetDataUsingDataContract(....)
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
}
The simplest answer I've found was here:, using the channel factory.
I still don't know if it's the best way but it left my code looking clean enough. Below is a sample from my controller.
public ActionResult Index()
{
SettingsModel config = null;
// Set up a channel factory to use the webHTTPBinding
using (WebChannelFactory<IChangeService> serviceChannel =
new WebChannelFactory<IChangeService>(new Uri(baseServiceUrl )))
{
IChangeService channel = serviceChannel.CreateChannel();
config = channel.GetSysConfig();
}
ViewBag.Message = "Service Configuration";
return View(config);
}

Dynamic IIS hosted WCF Service with TCP binding

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.