I have a wcf service which hosted at IIS
<%# ServiceHost Language="C#" Debug="true" Service="MyService" Factory="InitializableServiceHostFactory" %>
my problem is that the CreateServiceHost is called with each request to MyService method, which make my initialization code which is written in CreateServiceHost is called multiply.
After I checked a lot about this problem, I saw that it is related to ASP.NET dynamic compile, it is recompile the whole site when any things inside Bin folder is changed, but my WCF service writes to the temp folder inside Bin folder which make the site recompiled then the Application_Start re-fired, then the InitializableServiceHostFactory re-create the WCF service
I know it is a dummy problem :(
I suspected that the service host was not an instance of the service class, and Carlos Figueira confirmed that in his answer to [Is it necessary to Dispose() when using a custom ServiceHostFactory?].
The CreateServiceHost() in the factory was being called multiple times for my application, throwing an ArgumentException the second time it was initialized, with the message:
The value could not be added to the collection, as the collection already contains an item of the same type: ....
WCF sometimes reuses the service host. I worked around the problem by checking if any of my customized behaviors were already in the servicehost's Description.Endpoints.Behaviors list, so I didn't initialize my service host a second time. In practice, my case was simpler because I was setting the ServiceAuthorizationManager; if I found it set already, I avoided initializing anything again.
Related
I have created a WCF service using Workflow. It works just fine. I created another Workflow application to consume it. I added the service reference to the application project and rebuilt the project. I added the component from the service to the app, but it's expecting an argument that I never specified.
I've tried rebuilding both the service and the app, generating an entirely new solution and starting from scratch - same problem. I've looked at others' code and they've structured this project the same as mine but this issue does not show up on theirs. Googling this problem seems to bring up not results.
My workflow service is defined as such: https://i.imgur.com/E8mEfs6.png
The parameters of the receive component are: https://i.imgur.com/TaNRw2y.png
But when I add it to my app, the parameters are defined as: https://i.imgur.com/tqgEwNr.png
Which is not what I had defined in my service. I can't even figure out what it wants me to pass in for _GetCityStateFromZip. It says the type is InArgument.
I was expecting it to be expecting the zipcode parameter as I specified in the service. I think I might be adding the service reference incorrectly, but I don't know how. I went to Add Service Reference in Visual Studio, then copy/pasted the path to the .xamlx file of the service on localhost.
Thank you.
I found a solution to this problem here:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/5279fc5f-8a53-43e7-8ef2-3073808dc90f/configuring-workflow-services-how-to-configure-workflow-control-endpoint?forum=wfprerelease
I re-made my service using the steps listed and it works as originally intended.
I have a problem trying to initialise my IOC container in a WCF application. The application is non HTTP based using WAS.
When I start the application I get this error message...
Kernel was null, did you forgot to call DefaultServiceHostFactory.RegisterContainer
I have seen other answers to this solution which say to do the following...
Add a Factory definition to the ServiceHost definition e.g.
Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration"
Create a class in th App_Code folder with a static method called AppInitialize(). This method should then automatically be called and you can use it to register your container.
I have done this but my AppInitialize method is not called and I am still getting the error above.
Thanks.
I understand there are other similar questions, but I haven't been able to find a working response.
I create the default WCF service from the template [which comes with GetData() and GetDataUsingDataContract()].
It runs fine in the browser.
I have a separate web site to which I add this new WCF service:
I do 'Add Service Reference', enter my URL, the service comes up and I click 'OK' to add it.
Under 'App_WebReferences', I see the namespace of my added service: 'ServiceReference1', with 'References.svcmap' under it, and a couple .svcinfo/.wsdl/.xsd files under that.
No proxy files are created, but <system.serviceModel> element is added to my web.config, with what seems to be proper information.
However, with no proxy, I can't access/call any methods in my service (ie ServiceReference1.WCFMethod1())
I can call svcutil, generate the proxy, add it to my App_Code, and everything works as it should.
My question is, why isn't my proxy being created with 'Add Service Reference'?
Everything is under target framework: .NET Framework 4.
EDIT:
Just created a Console App and added the service reference and it created the proxy.
So the issue is my web site is not creating the proxy...
I had this same problem and found that unchecking Reuse types in all referenced assemblies did solve the problem. However, in my case, I needed it to reuse types from some of my referenced libraries. I found this post, covering a very similar problem. In that post, it references a Microsoft knowledge-base article which describes a fix for the the following issue:
Consider the following scenario:
You create an ASP.NET MVC4 Web API project in Visual Studio 2012.
You add a WCF service reference in the project.
In this scenario, the Reference.cs file for the service reference is empty.
Cause
This issue occurs because the DataContractSerializer class has encountered a type (Newtonsoft.Json.Linq.JToken) that it does not support. In this case, it throws an exception, and then stops generating the service reference.
I wasn't referencing that JSON library, but, based on that bug description, I surmised that one of my referenced libraries must have had a similar problem. I figured that one of the libraries that I was referencing probably contained a type that was not supported by the DataContractSerializer, it was throwing the same kind of exception, and it was therefore failing in the same way.
Sure enough, I found out that, in my case, the culprit was one of my own libraries which happened to include a public proxy for the same WCF service. I suspect it was that public proxy that was causing the trouble. In any case, by selecting Reuse types in specified referenced assemblies, and then selecting all of the assemblies except that one, the service reference automatically generated the proxy classes correctly.
When you are adding a ServiceReference : References -> Add new service reference.
Clik on advanced button and uncheck "Reuse types in all referenced assemblies".
This option sometimes causing errors.
Here is the main issue.
The issue source is when you are not able to find Add Web Reference in your visual studio. If the service is asmx, in my case it wasn't generating proxy class until I found these steps -> click on Sercice Reference -> Click on Advanced -> There you will see Add Web Reference... Provide your service URL hit OK issue resolved.
Hope this helps.
I´m creating a new WCF service. I initially had only three operations. But after some time I decided to add two more. This operations doesn't appear in the Microsoft test client, neither in the list of operations when I try to add a service reference from my WPF client. Also I tried to comment one of the initial operations. It still apears in the Microsoft test client and can be invoked. I Tried also delete the dlls generated by the service and regenerate again. No luck. There are some kind of "cache" where Visual Studio stores the WCF services libraries that I can delete?
UPDATE: I'm working with the service running in the ASP.NET devolopment server.
You need to understand the order in which things happen.
You change your code, adding methods with [OperationContract] on them, or removing them, or changing their parameters or return values.
You then must build your service, producing a .DLL that contains the changes.
You must then deploy the changed DLL to the server it's going to run on
You must then restart the service (this may happen automatically depending on the server. For instance, IIS will recycle the service when it sees that the DLL changed)
You must then update your client, either the WCF Test Client, or "Add Service Reference", or the equivalent.
This last will have the effect of sending a request to the service for the new metadata or WSDL. Only then can the client see the changes you made to the definition of the service.
I don't know why, but I created a new project and copied the definitions of the operations from the problematic project and the problem is gone. One case more for Microsoft mysteries.
Make sure you are updating the services after adding the new operations.
Also make sure they have the attribute [OperationContract].
One thing we have discovered is that when you deploy the dlls that they must be in the bin, and cannot reside in the debug or release folder.
For me worked: just rebuild the wcf project
Did you close the client connection in client side
as showing your service
class Test
{
static void Main()
{
LocationClient client = new LocationClient();
// Use the 'client' variable to call operations on the service.
// Always close the client.
client.Close();
}
}
SOLUTION HERE :
Make sure your dataContract does NOT contain any enum
(You can use integer instead)
Be sure to reference a project in the solution and not a dll on your disk
Remove your "bin" and "obj" folders
Recompile
In IIS recycle the application pool
In IIS restart your service
In IIS "Browse" your service
=> You got it
I have a sharp architecture project and I am making use of ApplicationServices in it as well.
There is requirement to provide a winform client that will use a wcf service. The wcf service will in turn use the ApplicationServices. I have not started working on the winform client yet but I am working on the wcf service.
Following the Northwind sample. I have created a "Wcf Service library" project and a "Wcf Service Application" project in my solution.
I am new to wcf but i know all the basics and have worked with web services alot in the past. I have following questions:-
1) I would like to know why there is a need of two projects, wcf library and wcf application?
2) I have noticed that the ITerritoriesWcfService interface in the Northwind sample inherits ICloseableAndAbortable.
public interface ITerritoriesWcfService : ICloseableAndAbortable
What is the purpose of ICloseableAndAbortable?
3) There is another class TerritoriesWcfServiceClient
public partial class TerritoriesWcfServiceClient : ClientBase<ITerritoriesWcfService>, ITerritoriesWcfService
What is the purpose of this class?
4) In the TerritoriesService.svc file, what is the purpose of Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" ? Usually in a normal wcf service application, I use codebehind attribute, but since the .cs file actually resides int the wcf service library project, I would like to know what following code is doing?
<%# ServiceHost Language="C#" Debug="true"
Service="Northwind.Wcf.TerritoriesWcfService"
Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" %>
Even if I remove the above Factory attribute, I can still run the service app project and test the service using WcfTestClient utility.
6) When i run my service and using WcfTestClient If I run a method twice that accesses a repository, then on the second call, I get an ObjectDisposedException.
{"Session is closed!\r\nObject name: 'ISession'."}
I believe the NHibernate Session is getting disposed after the first call. How can reinitialise for each call or should I keep it open? I would like to know the best practice?
7) Also If I run the Northwind.Wcf.Web project and click on TerritoriesService.svc
file on the Directory Listing screen, I get the following error
{"Method 'Generate' in type 'Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator' from assembly 'Northwind.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.":"Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator"}
I don't understand why is it throwing this error, when i already got the method and the Northwind.Web works fine too.
Awaiting
Nabeel
1) Strictly, you can combine the WCF library and the WCF application
in one assembly. This would mean that you would combine the contracts
and the implementations in one assembly.
If you are using svcutil.exe or Visual Studio (which uses svcutil.exe
in turn) to generate proxy classes for your client, you'd be fine
because the proxy classes are generated from discovery of your
services.
If however, you want to use your own classes for transport, which is
quite common in DTO scenarios and the like, you'd need to reference a
shared library from both the client and the server. If that shared
library would be your combined library/application assembly, the
client would get the application implementation in scope (because it
references the assembly that contains the contracts) and that's really
not something you'd want. The client needs to know as little as
possible about the server, just as much as the contracts expose --
that's what the contracts are for in the first place.
I think it is best practice to separate interfaces/contracts from
implementation anyway because it leads to better separation of
concerns. It's just that most parts of your solution don't need (and
shouldn't) know HOW something is done, just WHAT that something can
do. There are many more advantages over this, such as improved
testability.
2) Taken from the code documentation of ICloseableAndAbortable:
"When implemented by your WCF contracts, they are then interchangable
with WCF client proxies. This makes it simpler to use dependency
injection and to mock the WCF services without having to worry about
if it's a WCF client when you go to close/abort it.".
I think that says it all.
3) The client class is, like the code documentation says, a strongly
typed client proxy. It can be used by clients to talk to the server,
providing a strongly typed class that has members that correspond to
the service operations that can be called on the server.
The advantage of this class is that you don't need to use the
svcutil.exe generated proxy classes. This what they mean by not having
to configure it via WCF configuration. This allows you to ship proxy
classes to your clients so they can immediately talk to your server
instead of generating proxy classes first. It allows for more control
as well, changing the code that is generated by the proxy class is
really not something you'd want to do.
This again is a good reason to put the interfaces/contracts in a
separate assembly because you don't want to ship the service
implementation code to your clients.
4) The service host factory creates a service instance based on the
provided service type. This can come in handy if you want to put the
service code somewhere other than in the code behind file. You'd also
need it if you are using Depency Injection, you'd provide the service
contract interface as the type and the SharpArch.Wcf service host
factory resolves it to the correct implementation class type by means
of the DI framework (Castle Windsor in SA). You can think of this as a
means of getting hold of a service implementation while not caring
about where it actually is coming from.
In this case, the service will run when you remove the factory
attribute, because the default factory is able to resolve the service
type. You're bypassing on stuff like DI and session management though,
exactly that what makes SA valueable.
5) I'll have to skip this one because apparently there is no question number 5 :-)
6) As in the Northwind sample project, you are probably using the ServiceHostFactory that comes with SA. With this service host factory, each created service instance is extended by a behavior that closes the NHibernate session directly after it's called. That okay by itself but chances are that your proxy clients are not managed in a transient way by Castle Windsor. Therefore instances get reused, including the closed sessions they (still) contain. Decorate your client proxy classes with the Transient attribute (Castle.Core.TransientAttribute) and Castle Windsor will create a fresh instance every time a service call is performed.
Apparently, there is a second way to solve this but it requires modification of the S#arpArchitecture code base. See WCF connections which process more than one request fail because the nhibernate session is closed and isn't re-opened. on GitHub.
7) I'm sorry, I seriously have no idea. I might look into this later.