I have an ASP .Net MVC 3.0 web application hosted on IIS and I am using Castle Windsor version 3.0.
What I would like to do is register a WCF service using the webHttpBinding without any entries in the web.config or having a .svc file. Is this possible?
I tried this in my IWindsorInstaller implementation:
container.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero);
container.Register(
Component
.For<IMyService>()
.ImplementedBy<MyService>()
.AsWcfService(new DefaultServiceModel()
.AddBaseAddresses("http://localhost/WebApp/Services")
.AddEndpoints(WcfEndpoint
.BoundTo(new WebHttpBinding())
.At("MyService.serv"))
.Hosted()
.PublishMetadata()));
And I am ignoring anything that finishes serv like so in my RegisterRoutes method in global asax:
routes.IgnoreRoute("{resource}.serv/{*pathInfo}");
If I point a browser at http://localhost/WebApp/Services/MyService.serv I get a 404.
What am I doing wrong or am I trying to do something stupid (or not possible or both!)?
Thanks to Ladislav's suggestion of using the ServiceRoute I have worked out how to do this, but I am not sure it is ideal, here is what I have done (in case Googlers find it and can improve it etc):
Created an extension method on ComponentRegistration like so:
public static ComponentRegistration<T> AddServiceRoute<T>(
this ComponentRegistration<T> registration,
string routePrefix,
ServiceHostFactoryBase serviceHostFactory,
string routeName) where T : class
{
var route = new ServiceRoute("Services/" + routePrefix + ".svc",
serviceHostFactory,
registration
.Implementation
.GetInterfaces()
.Single());
RouteTable.Routes.Add(routeName, route);
return registration;
}
What that does is adds a service route that places the service under the Services folder and tacks on a .svc extension (I will probably remove that). Note, I am assuming that the service implements only one interface, but in my case that is fine and I think is good practice anyway.
I'm not sure this is the best place to have this extension method, or even if an extension method is actually needed at all - perhaps I should be doing it with a service host builder or something, I don't know!
Then in the MapRoute calls I made sure to add this to the constraints parameter as per the question MVC2 Routing with WCF ServiceRoute: Html.ActionLink rendering incorrect links!
new { controller = @"^(?!Services).*" }
This just makes anything that starts Services not get matched as a controller. I do not like this very much since I would have to add it to all of my routes - I would rather globally make the Services folder fall into the service resolver or something (I do not know enough about MVC it seems!).
Finally in my windsor installer I register the service like so:
container.AddFacility<WcfFacility>(
f =>
{
f.Services.AspNetCompatibility =
AspNetCompatibilityRequirementsMode.Allowed;
f.CloseTimeout = TimeSpan.Zero;
});
container.Register(
Component
.For<IMyService>()
.ImplementedBy<MyService>()
.AsWcfService(new DefaultServiceModel()
.AddEndpoints(WcfEndpoint.BoundTo(new WebHttpBinding()))
.Hosted()
.PublishMetadata())
.AddServiceRoute("MyService", new DefaultServiceHostFactory(), null));
After that I can browse to the service and it is picked up and constructed fine!
As I allude to though, it might not be the best way to do this, but it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With