I have a server in Java which has some web-services. WSDLs (and XSDs) are generated from java using javatows from apache cxf.
Some services share types, and I would like to share these types also in wsdl is it possible?
After that I want to generate c# code using svcutils, but because in each WSDL are some copies of the same types svcutil tell error that this complex type has already been declared...
I know that I can use /namespace switch but I do not want this because that way I will have the same classes generated in different namespaces... I would like to have one class in common namespace...
I suggest you create a common.xsd file (if possible) containing the shared structures which are then included in each WSDL file for each one of the services.
<include schemaLocation="common.xsd"/>
I believe that will overcome the problems you're having when generating client proxy code with svcutil.exe.
Related
I am new to WCF service. I am aware about three ways to generate proxies.
Using Service reference
Using SvcUtil
Using ClientBase
But I am confused in which case I should use which type. In my case I have to generate proxies for third party service for which I don't have service code. I don't want to use add service reference because it gives me following issue. Mentioned in this stackoverflow question. So I want to use clientBase. But I think I cannot use it without using service reference. I am pretty much confused when should we choose which kind of proxies.
In my case I have to generate proxies for third party service for which I don't have service code.
I will have multiple apps using this service.
In that case you are better off using SvcUtil because it can generate a single library that all of your projects can use, even if they are .NET libraries. After it is generated you can always go in and tweak it.
Add service reference on the other hand is fine for a single .exe but as you have discovered, is annoying for multiple apps as you need to repeat the process and you end up with multiple definitions of WCF types that is just going to increase maintenance.
Just be sure to leave WCF client config in the app.config of your applications and not your app.config of your class library (as the former may not be read).
If your vendor had followed "WCF the Manual Way… the Right Way" it would have made your life easier.
SOAP purists would argue however that the only thing the vendor provides is a SOAP WSDL XML file from which you are required to generate your types anyway. (sadly, the default behaviour in .NET is back-to-front)
I imported a service reference using wsdl, this wsdl contains classes and methods, some of which to be implemented in my web service. Now, publishing my WS and trying to get the wsdl I notice a lot of differences between the imported one and the generated (namespaces, "ArrayOf" prefix in collections, ...).
I'm using just the classes provided by the original wsdl, so I can't understand why the wsdl of my WS has to be different...
I need to output a wsdl identical to the one imported because they will be both imported from my customer to make an interface, so everything has to be coincident.
Thank you
Without knowing more details, I don't see why your customer is being handed two WSDLs.
To simplify things just hand the generated WSDL from your web service to your customer. If there are things in the imported WSDL that are not in the generated WSDL I would just duplicate the missing pieces in your generated WSDL.
The generated WSDL probably contains more generic definitions of collections than what you provided so that it is compatible with different client languages.
Using SvcUtil I generated proxy for a SOAP WebService. This webservice has many complex types and can change every year. Is there a tool I can use to generate wrapper for all classes. Using composition in wrapper class I will call proxy class.
Svcutil.exe generate POCO types at the client sides according to the XSD parts of WSDL. There shouldn't be T4Template involved which is too complex and overkill and inappropriate. Svcutil.exe could have created all the proxy classes you need.
If the complex types may be changing every years, you may consider versioning.
Once an interface is published, you should not changed it. This applies to both operation contracts and data contracts.
You may refer to this article WCF for the Real World, and google WCF versioning.
So basically you explicitly declare XML target namespace in the contracts, and map CLR namespaces with XML namespaces. When you need to change the complex types, you have to provide another version of WCF service. During the transition period before all the clients could upgrade to the latest version, you keep both versions running.
I want to create a wsdl by using 3 xsd-files. How do you that?
I tried this in the command prompt:
wsdl.exe /language:cs /parameters: c:\myService\Contract\HeaderData.xsd c:\myService\Contract\MyData.xsd c:\myService\Contract\Messages.xsd /out: MyWsdl.wsdl
What do I wrong?
I believe that there's a misunderstanding here. Most likely the wsdl.exe in your illustration refers to Microsoft's tool, which is described as:
The Web Services Description Language tool generates code for XML Web services and XML Web service clients from WSDL contract files, XSD schemas, and .discomap discovery documents.
From what you seem to imply by asking the output to be a WSDL file, I can safely assume that you really try to create a WSDL file starting from XSD files. Below I am trying to explain why you cannot do that that easy, and what options you have.
The diagram below shows you the model behind the WSDL 1.1 specification.
Your XSDs fit exactly, and only under types. It WSDL terms, types represent your type system used to describe the parts that make up messages, which are then used to describe input/output and faults of operations organized as ports (abstract interfaces) bound to application/transport protocols, and ultimately made (physically) accessible as services at one or more network endpoints.
To generate WSDL(s) out of XSD(s), you realized by now that you need to provide some more data to a tool that would automatically generate a WSDL for you. For example, what operations you want to describe in your WSDL? For each one of them, what's the input, most likely the output and maybe one or more faults? How would you group them (portType = interface)? What binding do you want to use: HTTP, SOAP? What version of SOAP? SOAP over: HTTP, MQ? SOAPAction? How many WSDL files: 1, or maybe 3?
Some tools may ask you a series of questions (data entry/wizards) along the above lines and then create the WSDL(s) for you. Others, use predefined patterns in the implementation of XSD schema constructs (for example, IFX has a certain way to define Request/Response elements) so based on those assumptions a specialized tool such as QTAssistant (I am associated with it) would ask you less questions, while still creating the WSDLs.
I remember one or two online tools that were able to allow the user to upload XSD files and then create WSDL after prompting you a couple of questions, but I can't seem to find them anymore... kind of like this one...
From my understanding, you don't go xsd->wsdl, but I could be wrong.
Generating a WSDL from an XSD file might help clear it up for you though.
You cannot auto-generate a WSDL from an XSD in this manner. In order to create the WSDL, you need to start with a new WSDL and import this XSD.
The XSD defines the types of data that are available for services. Some XSD is usually embedded in a WSDL, some are imported specifically.
An alternate way is to use the XSD in C# to generate a service, and then extract the concrete WSDL from that service, but this is not preferred as many teams prefer contract first web services.
Consider the following Visual Studio project structure
ProjectA.csproj
AClass.cs
ProjectB.csproj
References
ProjectA
Web References
AWebService
AWebService.csproj
References
ProjectA
ReturnAClassViaWebService.asmx
The issue occurs when ProjectB adds the web reference to AWebService and automatically generates all the proxy code for accessing AWebService including a new implementation of AClass. Since all of our other code needs to use the AClass defined in ProjectA, we're forced to convert the AWebService.AClass returned from the service into something we can use.
We're currently considering two solutions, neither of which are ideal.
Manually editing the generated Reference.cs to remove new definitions of AClass
Serializing AWebService.AClass to a stream then deserializing to ProjectA.AClass
Does anyone have any better solutions? This seems like something common enough for other developers to have experienced it.
Ideally we would like to have the proxy code generated in ProjectB to reference ProjectA.AClass rather than generating a whole new implementation.
Our environment is VS 2008 using .NET 2.0.
I have had the same problem that you are describing and I have tried both of the options you specify without being entirely happy about either of them.
The reason we both have this issue is at least partly because the shared-library-between-consumer-and-provider-of-a-web-service-solution is in violation of accepted patterns and practices for web service design. On the consumer side, it should be sufficient to know the interface published in the WSDL.
Still, if you are prepared to accept a tight coupling between your web service provider and web service consumer and you know for certain that your current client will never be replaced by a different client (which might not be capable of referencing the shared library), then I understand why the proposed solution seems like a neat way to structure your app. IMPORTANT NOTE: Can we really honestly answer yes to both of these questions? Probably not.
To recap:
The issue appears when you have classes (e.g. a strongly typed dataset) defined in some sort of shared library (used on both client and server).
Some of your shared classes are used in the interface defined by your web service.
When the web reference is added there are proxy classes defined (for your shared classes) within the web reference namespace.
Due to the different namespaces the proxy class and its actual counterpart in the shared library are incompatible.
Here are four solutions that can be tried if you want to go ahead with the shared library setup:
Don't. Use the proxy class on the client side. This is how it is intendend to be done. It works fine unless you simultaneously want to leverage aspects of the shared library that are not exposed by the web service WSDL.
Implement or use a provided copy/duplication feature of the class (e.g. you could try to Merge() one strongly typed dataset into another). A Cast is obviosuly not possible, and the copy option is usually not a very good solution either since it tends to have undesirable side-effects. E.g. When you Merge a dataset into another, all the rows in the target dataset will be labeled as 'changed'. This could be resurrected with AcceptChanges(), but what if a couple of the received rows were actually changed.
Serialize everything - except for elementary data types - into strings (and back again on the consumer side). Loss of type safety is one important weakness of this approach.
Remove the explicit declaration of the shared class in Reference.cs and strip the namespace from the shared class wherever it is mentioned within Reference.cs. This is probably the best option. You get what you really wanted. The shared class is returned by the web service. The only irritating drawback with this solution is that your modifications to the reference.cs file is lost whenever you update your web reference. Trust me: It can be seriously annoying.
Here is a link to a similar discussion:
You can reuse existing referenced types between the client and service by clicking on the 'Advanced' button on the 'Add Service Reference' form. Make sure the 'Reuse types in referenced assemblies' checkbox is checked and when the service client is generated it should reuse all types from project A.
In past versions this has not always worked correctly and I've had to explicitly select the shared type assemblies by selecting the 'Reuse types in specified referenced assemblies' option and then checking the appropriate assemblies in the list box. However, I just tested this with VS 2008 SP1 and it appears to work as expected. Obviously, you need to make sure that the types that are being used by the service and client projects are both from project A.
Hope that this helps.
We encountered a similar problem with one of our projects. Because we had several dependencies, we ended up creating a circular reference because project 1 required objects from project 2, but project 2 could not be build before project 3, which relied on project 1 to be build.
To solve this problem, we extracted all the public standalone classes from both projects and placed them inside a single librarie. In the end we created something like this:
Framework.Objects
Framework.Interface
Framework.Implementation
WebService
The WebService would be linked to all projects in our case, whereas external parties would only be linking to the objects and interface classes to work with. The actuall implementation was coupled at runtime through reflection.
Hope this helps