Can WCF services running in WcfSvcClient run under a domain account? - c#

I have a client where I'm trying to port their code to my machine for development purposes. They built their wcf services using classes and interfaces only - thus no svc files. Almost like you would find with self hosting.
When I run the application, these services are hosted by WcfSvcClient (for debugging purposes) and I can see them starting up. I can however not access these services by pointing my browser to the given urls, nor can I step into that code.
I know this should work, because it works on a client machine - but I cannot tell why it isn't working on my machine other than suspecting it needs a computer which runs on their domain?
The strange thing I've noticed is they declared a host url in the wcf services config file for each service. This url is used when starting WcfSvcClient - but it is not configured anywhere else I can see i.e. not IIS. It just mysteriously exists and I have no idea how to call it, debug it or even under which account it runs. Is this configurable somewhere?
Could someone perhaps point me in the right direction? My knowledge with wcf is very limited. Thanks

Ok so it seems wsHttpBinding does support authentication where the domain the service is running on is relevant. This is it's default behavior. You have to explicitly tell it to not do so, by including:
securityMode=None
in your binding configuration. Not suggested for production.
For more information see this post: WCF slow ServiceHost.Open() call

Related

when and why to host WCF service?

I have been through WCF and related topics, created my first WCF service. It works fine but the problem is that I don't understand hosting concept.
Different tutorials do different things like some create separate console applications for it to host service then using it in Asp.net app but some doesn't host it in any place and just add reference to another project and use it.
I don't understand that when to host where and why?
Please help me in this issue. I am using Visual studio 2013 with .net 4 and asp.net c#.
Basically, a WCF service needs to be hosted somewhere, so that it can be accessed from somewhere else. There are several ways to do this (and probably more than I know about too), but two of the most simple and common ways are to host the service in IIS Express, or in IIS (Internet Information Server).
IIS Express
The simplest way to achieve the first (IIS Express), is to simply right click the project in Visual Studio, and select View in Browser. That will open a directory listing in your browser, and in that directory you should see a file ending in .svc. Clicking that file should open the service description page with text like:
You have created a service.
To test this service, you will need to create a client (...)
The URL to that page, is in effect the URL clients will need to connect to your service. It should look something like http://localhost:64835/YourServiceName.svc.
That means the service is hosted locally, at port 64835, and accessible for clients at that address. Since this is in IIS Express however, it will no longer be accessible once you've closed Visual Studio, since it only runs as part of it.
IIS proper
Hosting in IIS means your service will be accessible whenever IIS is running. Once installed, it will usually start up when you log in, and run silently in the background. When it is running, you can start your service simply by accessing the correct URL. If it is not running, it might take a few seconds to start it. The next time it is called, it should respond quickly.
Note that in IIS, an application will by default run on port 80, which is the default port checked by browsers and possibly other clients - which means you don't need to specify it as in the example above. The URL will therefor generally be something more simple, like http://localhost/yourservice/yourservice.svc (although you could configure it to another port, or another protocol (say https://.., or something else if you like).
Once configured, and the relevant port is open however, your service should be accessible to the rest of the world.
Note: From the outside world, the URL will be different; it could be something like:
http://123.456.789.123/yourservice/yourservice.svc, if that is your IP address, or
http://yourdomain.com/yourservice/yourservice.svc if you've set up a domain.
I would suggest you consider hosting under two categories:
Self Hosting
IIS Hosting
As per you question "when to host where and why", I would say that you self host a WCF service only during testing. Mostly, self hosting is not used in live/production environments. For production environments use ISS hosting.
Self-hosting would be useful for testing on the local machine and on the intranet, while IIS hosting would be useful over the internet.
However, one must be aware that there is no rule as such regarding the usage of a particular hosting technique in any particular situation. With experience, the developer will be the best judge.

WCF Client Not working when outside solution

I have created a WCF service hosted in a windows service.
Basically all the service does is that it gets data from the database, does some work in memory with it and save data back to the database.
i created a windows form client to consume the service.
Inside the solution of the service, i added a service reference to the service in the project and everything works fine, however when i installed the service and run it, i created a separate client project and referenced the hosted service.
When i call the function that does the work, it doesn't work. (it must update a flag in the database)
Can you please suggest what may be causing this problem, i have not posted any code example because the code is too big, mainly it uses ado.net, Nhibernate ...
If the service is in another project it is likely not running when the second project attempts to access it.
Either setup IIS to expose the service (this is normally how a production environment would be setup) or as a test, use the IIS Light (Cassini) that is provided with Visual Studio to host the service.
Once either of the choices above have been implemented, configure the client to use the service - the URL likely changed.
I found the solution.
The configuration of my WCF has to be placed in the configuration file of the host, which is a windows service in my case.

WCF - Self hosted or IIS Preference?

I am relatively green with C# and WCF. I have landed on a project where I am creating self hosted WCF services running as Windows services but am starting to wonder if I should use IIS instead (which we don't currently use) as managing all of these services could eventually get cumbersome.
Despite my best efforts, I have yet to find any definitive information about why I might favor one approach over the other. The services are primarily used for utility stuff like resizing images, retrieving files, etc. and are called by both C# and Java clients.
Thanks
The shortest answer would be 'it depends'. On your requirements. You can self host without problems, but IIS will manage resources more effectively and enable you to fine tune stuff more easily than self-hosted.
For instance, in IIS would be more simple to deploy a new version or remove and old one.
Either way is fine.
Generally, using the builtin IIS hosting capabilities can make deployment and configuration simpler for you. Also you have the activation model of http.sys - which means IIS will start the necessary process for you when an appropriate message arrives.
Clients of any platform can connect to the WCF services regardless whether they are self-hosted or IIS hosted.
ps: how to allow IIS-hosted WCF services to store their configuration data in distinct xxx.config files

How to access info about where the WCF service is deployed

I have one WCF service deployed in multiple websites hosted in IIS7 and sometimes (development environemnt) in VS2010.
Often multiple instances are connected to the same database and usually its not a problem as its read-only access, but sometimes (like in logging) I need to uniquely identify instance of the service accessing DB.
Currently I do it by putting special attribute in web.config which I'll later use as a part of primary key, but I do feel its not ideal solution.
I thought about site-name in case its hosted in IIS and machine name + port if its hosted from VS2010.
And here comes the question: How to access info about where the WCF service is deployed and how to do it programmatically from inside of deployed service in c#? Is it at all possible?
Thank you for your suggestions.
Michal
The other day there was a question about how to get the IP address of the WCF server, for logging. This topic might help: How to get IP address of WCF web service
You could also determine if you are running in IIS by finding out what process your app is being run from using System.Diagnostics.Process.GetCurrentProcess(), and see if it is "w3svc.exe", which is what the IIS app pool runs as.
If I understand your question correctly, and I may not, you would like to know were on the server the actual instance is deployed.
If this is the case you can use something like:
(string)AppDomain.CurrentDomain.GetData("APPBASE")
Or I believe this will also work:
AppDomain.CurrentDomain.BaseDirectory;
Using reflection on the assembly or process itself will not work because the running process is the host (IIS, IISExpress, etc), but the two methods I specified should give you the location of the service itself for hosted apps.

Azure: Intra-WebRole Communication (netTcpBinding) with Full-IIS

I need to change some configuration settings on-the-fly in a Windows Azure project - and they need to be changed via a web service call (updating the application's configuration either via the platform api or the Azure Management site isn't an option here).
The project has multiple web and worker roles - all of which will need to know about the new configuration when it is changed.
The configuration is persisted to durable storage, and it's also cached during runtime in a static variable.
My solution was to create an internal (tcp) endpoint on my roles, and use that to loop through all of the roles and instances within those roles, create a client on the fly, and tell the instance about the new setting. (pretty much identical to: http://msdn.microsoft.com/en-us/gg457891)
At first I started a ServiceHost in the WebRole's RoleEntryPoint... and I was confused why everything seemed to be working fine when I stepped through the communications (the static variables where getting set correctly) - yet when I'd make other webservice calls, the static variable seemed to have "forgotten" what I set it to.
This was the case both locally, and in the Azure staging environment.
At this point I realized that because we're using full-IIS mode, the RoleEntryPoint and the Web Services were running in two separate processes - one in Azure's stub, and one in IIS.
"Not a problem" I said, I'll simply move the line of code which starts the ServiceHost from my RoleEntryPoint into the global.asax - at which point the ServiceHost will have been started in the same process as the rest of the site - and the static variables would be the same ones.
Here's where I'm having a problem; This works great on my local machine running in the dev environment. As soon as I deploy to staging I start getting error emails saying the channel used to connect to the service can't be closed because it's in a "faulted state".
Question:
What's different about Azure vs. Dev environment that is causing this?
How can I fix or workaround the problem?
Does anyone have any general advice on how I should go about obtaining a more descriptive error... do I have to enable full wcf diagnostics in Azure to get this, or is there some other way I can get at the exception details?
Follow-Up:
Via remote desktop i've learned several interesting things:
Non-HTTP Activation isn't installed by default on Azure WebRoles. I believe this can be overcome via a startup script:
start /w pkgmgr /iu:WCF-NonHTTP-Activation;
The website created in IIS by the web role doesn't have the net.tcp protocol enabled by default. I also believe this can be overcome with a startup script:
%systemroot%\system32\inetsrv\appcmd.exe set app "Website Name Here" /enabledProtocols:https,http,net.tcp
I haven't had time to take this all the way, as deadlines have forced me to implement some workarounds temporarily.
Some useful links related to this topic:
http://msdn.microsoft.com/en-us/magazine/cc163357.aspx
http://forums.iis.net/t/1160443.aspx
http://msdn.microsoft.com/en-us/library/ms731053.aspx
http://labs.episerver.com/en/Blogs/Paul-Smith/Dates/2008/6/Hosting-non-HTTP-based-WCF-applications-in-IIS7/
UPDATE (6/27/2011):
Amazingly, someone at Microsoft (whose blog I commented on) actually got me an answer on this.
The Azure & WCF teams updated this post:
http://blogs.msdn.com/b/windowsazure/archive/2011/06/27/hosting-services-with-was-and-iis-on-windows-azure.aspx
The link contains all of the information you need to get going with this.
And a HUGE thanks goes to Yavor Georgiev, the MSFT PM with the win.
It's been quite a while since I've asked the question, and no answers, so let me leave this:
Per my follow-ups in the post, there are ways of making this work... but they are complicated and difficult to implement.
For WORKER ROLES, netTcpBinding works perfectly. No issues here. Go ahead and use it.
For WEB ROLES, you've got problems.But netTcpBinding is what you need to use for exposing internal endpoints. What to do?
Well, here's what I did:
Start netTcpBinding service in your RoleEntryPoint using ServiceHost.
Create standard WCF service in your web role using SOAP / JSON / Whatever you want.
When you receive requests through your netTcpBinding, proxy them along to the WCF service on the loopback adapter.
Properly secure your "internal" WCF service with SSL client certs.
It's not perfect... but it works, and it's not terrible.
I suspect that needing to do this kind of thing isn't super common, and I really can't think of any reason why you'd need to other than to dynamically modify settings at runtime... which means you're not slamming these services like crazy.
Obviously, YMMV.
I had a miserable time getting HTTP working between instances in staging, and gave up when it looked like I needed to mess around with netsh to give my processes permission to listen via an HttpListener (sheesh!). So I switched to TCP via sockets. HTTP just adds overhead in a point-to-point communication scenario like this.

Categories

Resources