I am attempting to replace a WSE service with the WCF equivalent where the WSDL is provided externally.
First, I used svcutil and wsdl to generate all the service and client classes (ATP, I'm only concerned with the service implementation.) I generated an empty WCF Service Library project and replaced/renamed the IService1.cs with a class named for the interface ServiceContractAttribute generated. I then renamed the implementation class Service1.cs with the name of the implementation-class JINDEXWcfListener.cs. I removed the generated code from this class and created class definition JINDEXWcfListener:[interface name].
The tool auto-generated the implementation of the interface. I used the single method adorned with [OperationContractAttribute] to put my local implementation code. I modified the default app.config generated to adjust the contract and service names as required.
When I start debug, I can see that the service is starting in the WTC. However, when the single operation is exposed, the is a red dot with a yellow question mark in front of the operation name. When I RC on the op name, I get "This operation is not supported in WCF Test client" with no additional information. What is wrong?
WCFTestClient has quite a few limitations. I have fought "problems" for several hours that later turned out to be just WCFTestClient problems. Complex objects can give you a lot of grief, also any custom lists, etc such as a custom implementation of the IList interface. Try out WcfStorm. I think they have a free version and a trial version.
Related
I went through many posts but, i did not able to clear my some of basic doubts related to WCF service as follow:
Why should we keep separate class library projects assembly for Service.Contracts and Service.Implementation ?
we can implement one interface multiple times even it in single assembly.
It suppose to create - WCF Application project and maintain interfaces into separate folder and SVC.cs file separately.
Add service reference is not good option as it adds all the schemas into client side.
svcutil.exe is also do same thing. Then, what is the best way to consume wcf service at client side ?
All is explained in this great article - WCF the Manual Way…the Right Way.
Essentially, Add Service Reference and svcutil just lead to client proxies that become out of date over time; and the fact that the solution has multiple types defined for what are essentially the same class.
Update: Since writing this answer I have learnt not to have answers in another castle so I update below:
Essentially, WCF the Manual Way…the Right Way describes that rather than using Add Service Reference, you instead divide your WCF system into separate dlls for:
Contracts
Service implementation
Roll-your-own client proxies
Both the service and client add normal code references (not service references) to the contracts dll.
In this way, the service and client are using the same types (and not code-generated ones in the client) and when the contract changes - both the service and client are forced to update less a compile error appears. No more out-of-date clients.
I have a .NET WCF service (not a web service) with many methods, some accepting and returning complex data types. I use these services from my Windows Phone 7 apps. It all works great and it's easy.
Now I'm evaluating the feasibility of porting some of my apps to Android, but I can't figure out how to invoke my WCF services from an Android client.
I have a working example I found in Invoke webservices from Android.
But this looks to be accessing a "Web Service", not a WCF Service.
My service is at http://www.deanblakely.com/Service2.svc, and it contains a simple method named "SimpleTest" that just returns the string "Alive".
Using the code in the linked article, I put http://www.deanblakely.com/Service2.svc in SOAP_ADDRESS and SimpleTest in OPERATION_NAME. But I have no idea what to put in SOAP_ACTION and WSDL_TARGET_NAMESPACE. I don't even know if this approach is valid.
In .NET, Visual Studio builds us a "Service Reference" and everything just works.
I also don't understand the following two lines of code...
httpTransport.call(SOAP_ACTION, envelope);
Object response = envelope.getResponse();
With WCF services, the call is async so we make the call to SimpleTestAsync and leave a callback for the async return. These two lines of code appear to be synchronous, no?
When communicating with WCF services from a non-Windows client, you are basically treating it as an XML Web Service. If you configure your WCF service to use a basicHttp binding, it will act just like any other web service, as far as Java is concerned.
Normally, to call a WCF service from Java, you use wsimport to create a custom set of proxy and data classes, similar to the way a service reference works. Android doesn't have all the libraries needed for those classes, but I did find this URL:
http://code.google.com/p/androidclientgenerator-wsimport/
That is a proxy class generator specifically for Android. Instead of using the code on that web page, you may want to download this proxy generator; you simply have to pass it the URL to your service's WSDL page and it will create typed Java classes for everything. If you have complex types being passed back and forth, this is probably a much better option.
However, if you want to continue with the sample code, you'll need to fill in those variables you've identified. The variables are just the typical parameters for a SOAP envelope. These are defined in the WSDL for your service, and are primarily based on the namespace that you have defined for your service. (They are largely independent of the actual URL that your service lives at, with one exception). You specify the namespace in the WCF service contract:
[ServiceContract(Namespace = "http://namespaces.deanblakely.com/wcf")]
Note that the namespace URL doesn't need to point to a real resource, though frequently they do. It doesn't even need to be a URL (I often use urns); it just needs to be a unique string of characters. For now lets assume you assigned the above namespace to your service.
The WSDL_TARGET_NAMESPACE is just the namespace, exactly as above. The OPERATION_NAME is the name of the method you want to call, for example SimpleTest. The SOAP_ACTION is the combination of namespace an operation; in your case that would be http://namespaces.deanblakely.com/wcf/SimpleTest. In your WSDL you would see this described in an operation tag:
<wsdl:operation name="SimpleTest">
<soap:operation soapAction="http://namespaces.deanblakely.com/wcf/SimpleTest" style="document"/>
The SOAP_ADDRESS is the only one that actually points to your service file, e.g. http://www.deanblakely.com/Service2.svc.
Hopefully that will get you started calling in to your web service; if not feel free to stop back and get more assistance.
EDIT: Missed the part about async calls.
Yes, the method described on that web page is synchronous. WCF service methods are synchronous by default, with the option to include asynchronous calls when generating a service reference in Visual Studio. wsimport generates async-ready proxies, so using the Android client generate may also help you out in this area.
I have a WSDL file from a published ASMX web service. What I am after
is creating a mock service that mimics the real service for testing purposes.
From the WSDL, I used SvcUtil.exe to generate code. Apparently it also generates
the server side interface.
Well the issue is that it generates very chunky interfaces. For example, a method
int Add(int, int) is showing up in the generated .cs file as AddResponse Add(AddRequest). AddRequest and AddResponse have a AddRequestBody and AddRequestResponse and so on.
The issue is that, to implement, I need to create the body and response instances for each method, even when I just want to return a simple int result.
Why can't it generate the method signature properly? Is there a better way of generating WCF Server side interface/contracts from WSDL?
The message structure you are describing is caused by two things:
better interoperability across web service stacks and their programming models (RPC vs messaging);
flexibility to accommodate new parameters into existing web services.
You are not the first one to complain about it, or the last. It's a WSDL binding style commonly called the document/literal wrapped pattern. It produces document/literal web services and yet also supports an RPC programming style. It's very "WS interoperability friendly", so to speak...
The WS-I Basic profile specifies that the soap:body must have only one child element and in this case it's a wrapper for the operation name that's being invoked. The parameters of the call are packed into only one element as a best practice since it's more flexible to later changes. In case of WCF you usualy end up with a MessageContract which has one MessageBodyMember which wraps all the parameters.
Basically, you are seeing the results of web service battles fought long time ago.
Here is some extra reading on the subject (and that's just the tip of the iceberg):
Which style of WSDL should I use?
RPC/Literal and Freedom of Choice
My Take on the Document/Literal 'Wrapped' Idiom
I have a WCF service that I'd like clients to be able to reference using Visual Studio's "Add Service Reference" feature. They've been able to recognize the metadata endpoint, the interfaces, methods and data types appear in the Add Service Reference dialog, and it appears to successfully generate the proxy without a hitch - but when viewing the generated code file or viewing the classes in the object browser, there is no service interface generated from the ServiceContract - only the DataContracts are represented. When I point svcutil at the same endpoint URL from the command line, the generated file does contain the interfaces.
The service itself has been used in production for a while and seems to work fine
It uses a custom binding, but the exact same binding configuration (and other config settings) are used by another service that seems to work fine with Add Service Reference
One thing that is different is that this service uses a custom behavior (an attribute derived from IServiceBehavior). The interface is also in a different assembly from the concrete service type, although so are the data contracts.
Update:
What seems to be causing the problem, which I'd somehow overlooked, is that there are FaultContracts for some of the methods on this interface, and these FaultContracts are referencing an exception type that is [Serializable], not [DataContract] (as I think anything that derives from Exception must be). The exception type itself is represented in the generated code, but its public properties aren't (in either svcutil or ASR-generated code)
What seemed to be causing the problem, which I'd somehow overlooked, is that there are FaultContracts for some of the methods on this interface, and these FaultContracts are referencing an exception type that is [Serializable], not [DataContract] (as I think anything that derives from Exception must be). The exception type itself is represented in the generated code, but its public properties aren't (in either svcutil or ASR-generated code)
In Understanding WCF Services in Silverlight 2, the author, David Betz, explains how to call a web service without adding a service reference in the client application. I have a couple of weeks experience with WCF, so the article was over my head. In particular, although the author gave a lot of code snippets, but does not say what goes where. In the article, he provides two different code snippets for the web.config file, but does not clarify what's going on.
Looking at the source code there are four projects and two web.config files.
So far, I have been using the standard Silverlight project configuration of one project for the web service and one for the Silverlight client.
Firstly, does the procedure described in the article work with the standard two project configuration? I would think it would.
Secondly, does anyone know of a simpler example? I am very interested in this, but would like to either see source code in the default two project setup which is generated when a new Silverlight project is made, or find a step by step description of how to do this (eg, add a class called xxx.cs and add this code..., open web.config and add these lines...)
Many thanks
Mike Thomas
First, a little philosophy...
If you are a consumer of a WCF service that you did not write, adding a service reference to your client is really the only mechanism you have to enable interaction with that WCF service. Otherwise, you have no way of knowing what the service contract looks like, much less its data and message contracts.
However, if you are in control of both the client and the WCF service itself, adding a service reference to the client is a nice convenience, but I've recently been convinced not to use it. For one, it becomes a nuisance after the first few times you change your contract to remember to update your service reference. And in my case, I have several different C# projects that are consuming the WCF service, so I have to remember to update each one of them. Second, creating a service reference duplicates the contract definitions that are already defined in your WCF service. It is important to understand the implications of this.
Let's say your WCF defines the following type.
[DataContract]
public class Person
{
[DataMember] public string FirstName {get; set;}
[DataMember] public string LastName {get; set;}
}
When you add a service reference to your client, the metadata associated with this class is retrieved through the metadata exchange (MEX) endpoint, and an exact replica of this class is created on the client side that your client "compiles" against. So your WCF service has a definition of the Person class, and so does your client, but they are two different, distinct class definitions.
Given this, it would make more sense to abstract the Person class into a separate assembly that is then shared between the WCF service and the client. The added benefit is that when you change the contract definitions within this shared assembly, you no longer have to update the service reference within the client because it is already referencing the shared assembly. Does that make sense?
Now to your question. Personally, I've only used WCF within C# projects, not Silverlight. However, I do not think things are radically different. Given that, I would suggest that you watch the Extreme WCF video at dnrTV. It gives a step-by-step guide for how to bypass the service reference feature.
Hope this helps.
Let me try - I'm not an expert at Silverlight development, so bear with me if I say something that doesn't apply to Silverlight :-)
As Matt Davis mentioned, the "usual" use case is this: you add a service reference to a given service URL. In doing so, Visual Studio (or the command-line tool svcutil.exe) will interrogate the service and grab its metadata - information that describes the service, all the available methods to call, what parameter they expect etc. From this, it will generate a class for you (usually called the "client" or "client proxy"), which you as a client (=service consumer) will use to call the service. You can have this client proxy class generated inside your "normal" Silverlight client project, or you could possibly create your own "service adapter" class library, esp. if you will be sharing that client proxy code amongst several Silverlight projects. How things are structured on the server side of things is totally irrelevant at this point.
As Matt D. also mentioned, if you do it this way, you're getting copies of the service, its methods, and its data, in your client - those are identical in structure to what the server has - but they're not the same type - you on the client side have one type, the server has another (the fields and properties are identical though).
This is important to remember since the whole basic idea of WCF is message-passing - all that connects the client (you) and the server (the other end) are the messages and their structure - what method to call and what values to pass into that method. There's no other link - there's no way a server can "connect" to the client code and check something or whatever. All that gets exchanged is serialized messages (in text or binary form).
If you do control both ends, you can simplify things a bit - you can physically share the service contract (the definition what the service looks like and what methods it has to call into) and the data contract (the description of what data is being passed back and forth) on both the server side as well as the client side. In this case, you won't be adding a service reference, you won't be duplicating the service and data definitions, so things are a bit easier (but it only works if you're in control of both ends).
In this case, best practice would be to package up all that describes the service (the service interface with its methods and the data contracts) into a separate assembly (class library) on the server, which you can then copy to the client side, and reference directly from there (like any old assembly you might have). So in this case, you would typically have at least three projects in your solution:
your actual Silverlight client project
the website or web app hosting your Silverlight control for testing
the service interface assembly, which contains the service and data contracts
So there you have it - I hope I covered all the basics of what's going on, and why you would want to do one or the other thing. If you need additional info, don't hesitate to comment on this posting and let us know!
Marc