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.
Related
I've recently inherited a number of WCF webservices that are configured to use an ASHX handler within a web project to render the .SVC files in the form of http://example.com/Services/V1/MyService.svc. The services are running in the dev and production environments, WSDL comes up, and adding a service reference in a new project allows me to call MyMethod and get a response exactly as expected.
The error handling and logging story isn't great, so I'm trying to run the site locally and add a service reference to http://localhost:1234/Services/V1/MyService.svc. I can load the service at that URL and see the same WSDL that appears for the production environment, but when I try to use code similar to what's below to call my method neither the client nor the response objects are recognized the way they are when I connect to production.
using MyServiceTestProject.LOCAL_MyService;
//...
MyServiceClient test = new MyServiceClient();
MyServiceMethodResponse r = test.MyServiceMethod("arguments!");
I am able to see exactly one of the MyCustomObject classes that is only declared within my service and stops being available when I stop using the service reference, so I know that something is coming across even if it's not everything that one would expect.
The relevant parts of the Web.Config files are the same when I compare my local and dev/prod environments, and the project that's running locally is the one that was deployed to those other boxes.
Has anyone encountered this sort of behavior runnning a services project locally using IIS Express?
Edit:. The endpoints are different between the prod, dev, and local environments, using the same code in each one. Thanks for pointing out that detail I'd omitted originally.
After spending several hours on and off trying to solve this before posting the question, deleting and re-adding the service reference and restarting both my IDE and my computer to no avail, I've discovered that right-clicking on the name of the service and selecting "Update Service Reference" (circled in red in the screenshot below) would ultimately fix the problems I was seeing although VS sometimes required me to perform multiple updates before it would work.
Without performing the update, neither my attempts to delete and add the service back nor restarting Visual Studio/rebooting my PC would help address the issue. I'm not sure if it's something about IIS Express that causes the service reference to not be created with all of the necessary data the first time around or if it's one of a hundred other variables in my local environment, but at least there's a reliable way to get it working when it does fail.
I'm currently working on a WCF service which holds and processes all the data for an application, while a MySql database is used for persistence. The service currently works as a singleton (InstanceContextMode.Single) and supports multiple concurrent calls (ConcurrencyMode.Multiple). I'm not really sure what version of IIS the service is hosted in, but I believe it is IIS 7.5.
The problem is that there are some situations where if an exception occurs (eg.: while releasing ReaderWriterLockSlim locks), the service will be in a unreliable state and data may get corrupted (and written into the database) if users keep calling the service.
Currently I know of two ways of preventing users from calling the service: either closing the InstanceContext object (through OperationContext.Current) or raising an exception in IDispatchMessageInspector.AfterReceiveRequest if the service is in a faulted state. The problem with both of these two ways is that they make the service unavailable until I restart the server/application pool (which I can't, see note below) or re-deploy the service.
Important note: Although I have Full-Trust, the service is currently hosted on a shared server, so I can't restart the server or the entire application pool (if that is possible) because that would restart other people's services as well.
Update:
I tried unloading the AppDomain as #usr suggested, but that doesn't work as well: after unloading it, an exception is raised for every call to the service.
Currently I'm trying to find out what WCF/IIS uses as a condition to decide if the service should be created again. I noticed that in the code generated for the client checks if there is any channel available to communicate with the service; if there isn't, a new one is created. Thus, I tried to close all channels in the service: I tried closing OperationContext.Current.InstanceContext.OutgoingChannels, OperationContext.Current.InstanceContext.IncomingChannels, OperationContext.Current.Channel, and many other properties with "Channel" in their name, all of them with no success.
The way to warm-up anything in IIS prior to version 7.5 is using scheduled console application to ping your web site / services and warm them up. It's not a good fix but it works, it is easy and I saw it on every project which had to deal with this requirement.
Or If you are using IIS 7.5 then
You can use Windows Server AppFabric, it has Auto Stat feature to keep the service always on. But you need to be on IIS 7.5 to install App Fabric.
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
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.
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.