WCF service reference generates void methods from WSDL - c#

This is my first try trying to use WCF, so I'm guessing I'm doing something incorrect.
I'm trying to access a soap service defined by the WSDL at http://confluence.atlassian.com/rpc/soap-axis/confluenceservice-v1?wsdl I'm using VS2010, and I add a Service Reference to my project and point it to the URL there (or rather, our intranet install of it), but when I use the Object Browser to view the service, the operations on the interface are ALL void methods with no parameters. It seems that WCF is not reading the type information correctly. It doesn't give errors, but it's giving tons of warnings like the following:
Warning 1 Custom tool warning: Fault
named InvalidSessionException in
operation getPermissions cannot be
imported. Unsupported WSDL, the fault
message part must reference an
element. This fault message does not
reference an element. If you have edit
access to the WSDL document, you can
fix the problem by referencing a
schema element using the 'element'
attribute. Z:\TestLibrary\Service
References\Confluence\Reference.svcmap 1 1 TestLibrary
Warning 2 Custom tool warning: The
optional WSDL extension element 'body'
from namespace
'http://schemas.xmlsoap.org/wsdl/soap/'
was not handled. XPath:
//wsdl:definitions[#targetNamespace='http://confluence.atlassian.com/rpc/soap-axis/confluenceservice-v1']/wsdl:binding[#name='confluenceservice-v1SoapBinding']/wsdl:operation[#name='getPermissions']/wsdl:input[#name='getPermissionsRequest'] Z:\TestLibrary\Service
References\Confluence\Reference.svcmap 1 1 TestLibrary
What am I doing wrong? I tried changing the config of the service with a combinations of options, but I could never pull in the types from the WSDL correctly. I've been assuming that WCF will auto-generate the type classes along with the service interface. Am I supposed to figure out what types are in use in the WSDL and create the classes and data contracts myself, or is it something else?

Hhmm... interesting - I ran svcutil.exe from the command line against that URL you provided, and while I get a ton of warnings about WSDL issues, I do also get some code - something like:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.4952
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://confluence.atlassian.com/rpc/soap-axis/confluenceservice-v1", ConfigurationName="ConfluenceSoapService")]
public interface ConfluenceSoapService
{
// CODEGEN: Generating message contract since the wrapper namespace (http://soap.rpc.confluence.atlassian.com) of message getPermissionsRequest does not match the default value (http://confluence.atlassian.com/rpc/soap-axis/confluenceservice-v1)
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, Use=System.ServiceModel.OperationFormatUse.Encoded)]
getPermissionsResponse getPermissions(getPermissionsRequest request);
// CODEGEN: Generating message contract since the wrapper namespace (http://soap.rpc.confluence.atlassian.com) of message searchRequest does not match the default value (http://confluence.atlassian.com/rpc/soap-axis/confluenceservice-v1)
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, Use=System.ServiceModel.OperationFormatUse.Encoded)]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(RemoteException))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(Vector))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(RemotePermission))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(RemoteNodeStatus))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(RemotePageHistory))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(RemoteContentPermission))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(AbstractRemotePageSummary))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(RemoteSpaceSummary))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(RemoteSearchResult))]
searchResponse search(searchRequest request);
So I would try to use svcutil.exe from the command line to generate your ConfluenceSoapService.cs file and then use that to talk to your Confluence service.

Just encountered this problem on JIRA 4.4, and it DOES work if you use the older Web Reference instead of a Service Reference.
For instructions on doing this, see: Web Reference vs. Service Reference
This was the simplest solution for me, since I know JIRA is moving toward REST (away from SOAP) and I am just trying to quickly get up and running.

Related

Create assembly with datacontracts of WCF service

Here is my issue: in a project I have to consume 3 third-party wcf services. 2 of those contain the same objects and largely the same methods.
The user's role within the application determines which service to use. For example: Let's say the 2 services are ServiceRoleA en ServiceRoleB. Both services contain the method GetInfo() end return the InfoDetails object. The InfoDetails object has the exact same signature for both services.
If I just add 2 service references to my project I'll get the objects ServiceRolaA.InfoDetails and ServiceRoleB.InfoDetails. Instead, I need just one object InfoDetails. I only want to write just one routine to handle the InfoDetails etc.
My initial thought was to create an assembly with the datacontracts of the services and reference the assembly in my project. This way the service references can use the common set of objects. For this to work I have create the datacontract classes using svcutil and the wsdl, but I get error upon error.
When I try the following:
svcutil *.wsdl /dataContractOnly /n:*,DataContracts
/language:C# /out:XxxData.cs
I get the following error:
"Error: Type 'AuthenticationBase' in namespace 'http://schemas.datacontract.org/2004/07/xxx' cannot be imported. It references 'KindOfModule' from namespace 'http://schemas.datacontract.org/2004/07/yyy' but schema does not contain appropriate statement. Either change the schema so that the types can map to data contract types or use ImportXmlType or use a different serializer.
If you are using the /dataContractOnly option to import data contract types andare getting this error message, consider using xsd.exe instead. Types generatedby xsd.exe may be used in the Windows Communication Foundation after applying the XmlSerializerFormatAttribute attribute on your service contract. Alternatively, consider using the /importXmlTypes option to import these types as XML types to use with DataContractFormatAttribute attribute on your service contract."
Exporting the datacontracts as XML types is no option for my so the next thing to try was:
svcutil *.wsdl /dataContractOnly /n:*,DataContracts
/serializer:XmlSerializer /language:C# /out:XxxData.cs
Which resulted in the exact same error. So I decided to try the other mentioned option to use XSD.exe. But that is also nog working since I only have a WSDL and XSD.exe requires a XSD file. Are there any more options I can try? Please help!
You don't need to add service references or using svcutil to create the client proxies, that is easily done by hand.
Create a contracts assembly that contains all service interfaces and data contracts.
Reference that assembly from both the server(s) and the client (be sure to update the web.config and .svc files to reflect these changes)
Create client proxy classes for your services.
A client proxy is as simple as adding a class like
public class ServiceRoleAClient : ClientBase<IServiceRoleA>, IServiceRoleA
{
public InfoDetails GetInfo(GetInfoRequest request)
{
return Channel.GetInfo(request);
}
}
The only drawback is that you'll have to maintain the system.serviceModel node in the app.config file yourself.

WCF FaultException naming conflict

I have 2 WCF services (different projects) sharing a class library with a MyExceptions defined.
Both services uses:
[OperationContract]
[FaultContract(typeof(MyException))]
void op();
When I add both references in the client project I get:
Type namespace.MyException already defines a member called MyException
with the same parameter types.
Basically the classes has the same name so the constructor is defined twice.
Any Idea of how to change the Exception namespace?
Please note that:
I am using svcutils
the namespace option doesn't work.
Thanks
Create the proxy using svcutil /reference:SharedLibrary.dll. This way svcutil won't generate classes that it finds in the SharedLibrary.dll, so the client uses the class definitions from the assembly.
Don't forget to add a reference to the DLL in the client project, if you haven't already done so.
Besides the namespace suggestion what can be done is to edit the proxy code generated by SVCUTIL and remove the duplicate code for the MyException class.
The steps:
1. Create a proxy file for Service1.
2. Create a proxy file for Service2.
3. Add the proxies to the client.
4. Compile and it gives error for having MyException already being declared.
5. Edit either one of the proxies and remove the MyException class code.

/sharedtypes equivalent for svcutil.exe?

Building an app that is relying on a 3rd party provider who has a very verbose set of SOAP services (we're talking 50+ WSDL files). Each individual WSDL however has numerous shared type declarations. When generating client code with wsdl.exe, there used to be a /sharedtypes flag that would merge duplicate entries if a type was found several times.
When I attempt to generate my client code, I bomb on these overlapping types that the 3rd party includes in all their WSDL files.
svcutil /t:code /importxmltypes [mypath]/*.wsdl
Results in error messages alluding to the type collisions. For example, a couple samples of the error messages below:
Error: There was an error verifying some XML Schemas generated during export:
The simpleType 'http://common.soap.3rdparty.com:CurrencyNotation' has already been
declared.
Error: There was an error verifying some XML Schemas generated during export:
The complexType 'http://common.soap.3rdparty.com:NumberFormat' has already been
declared.
I do not have control over the output of the WSDLs. I do not want to have to edit the WSDLs by hand for fear of an error that breaks in a fashion at runtime that would be highly difficult to track back to our editing of the WSDL files. Not to mention that there are 50 some WSDL files that range from 200-1200 lines of XML. (Remind me again why we thought SOAP was the great salvation to us all back in the late 90s?)
Try specifying all the WSDLs in one command:
svcutil http://example.com/service1?wsdl http://example.com/service2?wsdl ...
This should automatically take care of duplicate types. Another option is to take a look at the /reference command switch:
/reference:<file path> - Add the specified assembly to the set of
assemblies used for resolving type
references. If you are exporting or
validating a service that uses 3rd-party
extensions (Behaviors, Bindings and
BindingElements) registered in config use
this option to locate extension assemblies
that are not in the GAC. (Short Form: /r)
This means that if you already have some types defined in some assembly you may include this assembly and svcutil will exclude types from it to avoid duplicates:
svcutil /reference:someassembly.dll http://example.com/service?wsdl
I was having similar problems. By defining different CLR namespaces for the different xml namespaces (using the /namespace argument of svcutil) i was able to get it working.
/namespace:http://www.opengis.net/gml,OpenGIS.GML
I have been using wsdl.exe to get round this because I work with some SOAP webservices which define the same data transfer objects at different endpoints. So I use wsdl.exe because it has the sharetypes switch. I'm not a WPF developer so I don't really care that the output does not implement IWhatever for WPF, but the classes generated are all partial so you can do some work to implement interfaces you care about in a separate file.

WCF Service that returns a custom class generates errors in Reference.cs

I have a WCF Service project in Visual Studio 2008 that contains about 12 methods, some of which return primitive types like bool or string. I also have a Visual Studio Unit Test Project that references the published WCF Service. The Test Project compiles successfully when all the return types are primitive.
If I add a new method to the service that returns a custom class, publish it and update the service reference in the Test Project, it doesn't compile. The errors are: -
The type 'PublisherFaultException' already contains a definition for 'Reason'.
The type 'PublisherFaultException' already contains a definition for 'PropertyChanged'.
Type 'Publisher.Test.LibraryReference.PublisherFaultException' already defines a member called 'RaisePropertyChanged' with the same parameter types.
all in the auto-generated reference.cs file.
The contract for the method of the WCF Service is: -
Page GetItem(string path);
and the Page class has the DataContract attribute and it's public properties have the DataMember attribute.
I'm reluctant to modify the Reference.cs file as I'll need to do this every time the Service is updated.
Anyone know why this is happening?
Stuart.
When you Add Service Reference, you get a 'reuse types in assembly' option - this is likely to be the key to sorting out the duplication.
Or do you have some Test References that are causing the duplication?
Also, have a look in the References section of the project tree and see if there is anything unexpected in there (do you have references to 2 assemblies that both contain Service References in the same namespace?).
Using auto-generated proxy class it is always pain.
To handle situation like this I using separate assembly with data contract classes and service interface.
Contract dll will have:
public interface IService
{
[OperationContract]
List GetContentList();
}
[DataContract]
public class ContentItem
{
[DataMember] public string Name;
[DataMember] public object Data;
}
The client will have reference to the Contract.dll.
Proxy will be created manually:
class ServiceProxy : ClientBase<IService>, IService
{
public List GetContentList()
{
return Channel.GetContentList();
}
}
The server dll will have reference to the same Contract dll.
So we will be able to avoid any errors with auto generated proxy.
Also the manually created proxy will be simpler, more manageable.
When adding the Service Reference, try clicking Advanced, and select "Generate asynchronous operations".
I think what was happening was that there were some asynchronous methods in the web service, with names ending in "Async", which would conflict with the methods generated in the References.cs.
e.g. imagine the web service contains 2 methods: (1)SayHello and (2)SayHelloAsync.
Generating using the default task-based method produces:
SayHello and SayHelloAsync for (1)
SayHelloAsync and SayHelloAsyncAsync for (2).
The conflict occurred because there were 2 generated methods called SayHelloAsync.
At least I think that's what was going on. Anyway setting "Generate asynchronous operations" worked for me.

Why does this WSDL file generate an empty service proxy in VS2008?

Why does this WSDL file generate an empty service proxy in VS2008?
If you look at the Reference.cs file generated, it's empty. Any ideas?
right click on service reference , cofigure , un-check “Reuse types in referenced assembles” and click OK. Try to Update Service Reference. This worked for me!
Have you read your error list? I got the following:
Custom tool warning: There was a validation error on a schema generated during export:
Source:
Line: 144 Column: 12
Validation Error: Wildcard '##any' allows element 'http://search.yahoo.com/mrss:text', and causes the content model to become ambiguous. A content model must be formed such that during validation of an element information item sequence, the particle contained directly, indirectly or implicitly therein with which to attempt to validate each item in the sequence in turn can be uniquely determined without examining the content or attributes of that item, and without any information about the items in the remainder of the sequence.
Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.XmlSerializerMessageContractImporter
Error: Cannot import invalid schemas. Compilation on the XmlSchemaSet failed.
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://fliqz.com/services/search/20071001']/wsdl:portType[#name='IVideoSearchService']
Custom tool warning: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.
XPath to wsdl:portType: //wsdl:definitions[#targetNamespace='http://fliqz.com/services/search/20071001']/wsdl:portType[#name='IVideoSearchService']
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:binding[#name='basicHttpBinding_IVideoSearchService_20071001']
Custom tool warning: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.
XPath to wsdl:binding: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:binding[#name='basicHttpBinding_IVideoSearchService_20071001']
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:service[#name='VideoSearchService']/wsdl:port[#name='basicHttpBinding_IVideoSearchService_20071001']
Custom tool error: Failed to generate code for the service reference 'ServiceReference1'. Please check other error and warning messages for details.
Edit: I did some digging, and I came across the following links:
MSDN Question
Blog Entry
I tried following the instructions by ScottAnderson in the first link, but was unable to generate a client proxy with them. Perhaps you can have better luck.
It appears the reason this doesn't work is because Fliqz is using XmlSerializer rather than DataContract/MessageContract for its contract definitions, and WCF doesn't want to play nicely with them and generates inappropriate WSDL. If you could control the original contract, you could probably fix the issue and be on your way; unfortunately, you may be entirely out of luck.
If you can get the ServiceContract interface and the types it exposes, you might be able to generate your own client by hand. Judging by some of the class names I see in there, it appears that Fliqz is exposing internal objects in their contract, so I doubt you could, you know, call them up and ask them for a .dll you can reference.
You could try to write out the interface and data / message contract types yourself by analyzing the WSDL and XSDs. Looks like it'd be a lot of work, though.
Sorry I can't help more. This seems to be a combination of poor WCF legacy support and poor architecture/design on the part of Fliqz.
Try adding it as .NET 2.0 Web Reference.
Go to Add Service Reference, then click the "Advanced" button. Then you're given to option to add it as a .NET 2.0 Web Reference. I did this, and got it to work. I couldn't via the standard "Add Service Reference"
I don't see any <wsdl:portType> elements in your WSDL - that might be the problem.
Also, are you creating your service from a live URL, or some files on disk? If you're using "on disk" files: did you also get the "wsdl0" file as referenced in this line here:
<wsdl:import namespace="http://fliqz.com/services/search/20071001" location="http://services.fliqz.com/LegacyServices/Services/search/R20071001/service.svc?wsdl=wsdl0"/>
Marc

Categories