I am looking for a way to use a WCF WebServiceHost without having to rely on the HttpListener class and it's associated permission problems (see this question for details).
I'm working on a application which communicates locally with another (third-party) application via their REST API.
At the moment we are using WCF as an embedded HTTP server. We create a WebServiceHost as follows:
String hostPath = "http://localhost:" + portNo;
WebServiceHost host = new WebServiceHost(typeof(IntegrationService), new Uri(hostPath));
// create a webhttpbinding for rest/pox and enable cookie support for session management
WebHttpBinding webHttpBinding = new WebHttpBinding();
webHttpBinding.AllowCookies = true;
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IIntegration开发者_开发百科Service), webHttpBinding, "");
host.Open()
ChannelFactory<IIntegrationService> cf = new ChannelFactory<IIntegrationService>(webHttpBinding, hostPath);
IIntegrationService channel = cf.CreateChannel();
Everything works nicely as long as our application is run as administrator. If we run our application on a machine without administrative privileges the host.Open() will throw an HttpListenerException with ErrorCode == 5 (ERROR_ACCESS_DENIED).
We can get around the problem by running httpcfg.exe from the command line but this is a one-click desktop application and that's not really as long term solution for us.
We could ditch WCF and write our own HTTP server but I'd like to avoid that if possible.
What's the easiest way to replace HttpListener with a standard TCP socket while still using all of the remaining HTTP scaffolding that WCF provides?
Your problem is not related to HttpListener.
Your problem is: * You have a oneClick application with limited permissions that * Tries to open a Server port.
This is a contradiction. An untrusted limited permission application should NOT OPEN A SERVER PORT. This is why this is not allowed per definition.
Have you tried opening a normal socket port? It should not work either.
In general, limited trust end user applications should not host a web service ;)
That said, I ahve been in a similar situation trying to use WCF in a driver communication scenario - thank heaven my application runs with full permission.
You can easily compose your own stack via CustomBinding, using the higher level protocol stuff "as is", and rolling your own version of HttpTransport that isn't backed by HttpListener or IIS. Do-able, sure, but it's a lot of work. Take the existing HttpTransport bits apart with Reflector- there are a LOT of moving parts in there. You could probably hack up a simple PoC over Socket in a day or two if you don't need anything fancy like HTTPS or chunking, but making it robust will be tricky. Here's a good wrapup of a bunch of resources (may be a bit dated now).
You could also look at ripping apart enough of Cassini to make it hostable in your app, and loading the WCF pipeline in there (via .svc files and the service activation handler)- it'd require writing very little new code that way, but still give you a fairly robust and tested webserver.
精彩评论