I'm working on an app that uses a web service. This is a private service so I cannot post the WSDL or generated code here so this is more of a question for some general advice rather than specifics.
I fed the WSDL into Sudz-c. The WSDL originally had some imports of XSD's that sudz-c would overlook so I copied these into the types section of the WSDL.
I use the generated code to make a request to the service but I'm finding that the request is missing a name space for the complex type objects I copied into the types section of the WSDL.
Again I know this is very general information but if anyone else has had a similar issue with Sudz it would be great to get your advice.
I know the thread has ended, but I found solution to this problem..
If a WSDL has external XSDs included/imported then YES, you are right to have those XSDs types copied over into WSDL (i.e. Directly EMBED it into WSDL rather than including/importing).. The generated Code is almost perfect in any sense since it generates types for XSD types as well.. but you might receive an ERROR (same error in multiple files).. which will be a missing BASE-Class of few request/response types.. after analyzing the code I realized that that missing namespace is nothing but the same SOAPObject object so I replaced that missing namespace with SOAPObject.h and used SOAPObject interface/class as the base class.
e.g. in my case
#include "SOAP.h"
#include "sudz.h"
#class sudz;
#interface sudzAbstractRequestType : sudz
{
}
(Note: 'sudz' is the unique name that you use when generate code using SUDZ-C website/project, in your case it can be different).
I changed the code to (everywhere in the project where this error was encountered):
#include "SOAP.h"
#include "SOAPObject.h"
#class SOAPObject;
//#include "sudz.h"
//#class sudz;
#interface sudzAbstractRequestType : SOAPObject//sudz
{
}
I hope this will help others... I was stuck for days but later got it working OK..
Happy Coding :)
One thing you might try is to make sure you fix your namespace in the actual service itself.
here is a link help get that done:
http://alensiljak.blogspot.com/2009/06/removing-httptempuriorg-namespace-from.html
Couldn't find an answer to this so ended up just hand coding the web service messages :(
Related
I'm trying to learn how to use WSDL's to call web services from a Grails project. I've been provided with the WSDL and some XML results for reference.
I've been able to generate Java code from the WSDL, and everything seems to be working correctly.
Here's the WSDL: http://www.restfulwebservices.net/rest/USAZipCodeService.svc?wsdl
And here is the XML: http://api.geonames.org/postalCodeSearch?placename=MN&username=demo
I am receiving this exception in my project:
ERROR client.WebServiceClientFactoryImpl$WSClientInvocationHandler - No namespace on "geonames" element.
javax.xml.ws.soap.SOAPFaultException: No namespace on "geonames" element.
It seems like it is saying that the XML returned isn't valid for SOAP? Am I missing/misunderstanding some pieces the puzzle here? It is all pretty new to me.
Edit:
I am trying to use a Grails plugin called cxf client: https://github.com/ctoestreich/cxf-client
It is configured with the following in Config.groovy (something could be wrong/missing here?):
wsdl = "http://www.restfulwebservices.net/wcf/USAZipCodeService.svc?wsdl"
namespace = "cxf.client.postalcode"
clientInterface = "cxf.client.postalcode.IPostalCodeService"
serviceEndpointAddress = "http://api.geonames.org/postalCodeSearch"
I guess you just sent the XML returned from http://api.geonames.org/postalCodeSearch?placename=MN&username=demo as a parameter to the web service. Obviously, from the WSDL description returned you can see there is no such element named geonames, so the SOAPFaultException exception is quite a fair result.
To fix it, you have to refer to the WSDL description carefully, to make sure the invoke method has the right parameters work with whatever defined in the USAZipCodeService WSDL description tags like <wsdl:operation> and <wsdl:message>.
Another issue: 2 different WSDLs were metioned in your invoker and Config.groovy. The former is a RESTful service, and the later is a SOAP one. They work with different invoke methods and parameters, so make sure your code has consistent invoker and parameters, too.
I am trying to import a WSDL into a SOAP-UI project - which is a simple tool for testing SOAP calls. When I try and import the wsdl I get the following error:
WSDLException (at /wsdl:definitions/portType/wsdl:operation[1]/wsdl:input):
faultCode=UNBOUND_PREFIX: Unable to determine namespace of 'nrns:getDynamicsUploadQueueRequest
From inspecting the WSDL I see that there is no xmlns:nrns declaration under the definitions area. I read in a forum that I can resave the WSDL to disk and correct the WSDL. However, I'm an extreme SOAP noob and I don't know what the definition is supposed to be. I think that if I just add the following to the definitions area it should sort things out. Anyone know what I would replace those question marks with? Am I completely wrong in my approach?
xmlns:nrns="???"
I don't own or have control over the WSDL. The WSDL and XML are below for reference.
https://apps.net-results.com/soap/v1/NRAPI.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name='NRAPI' targetNamespace='https://apps.net-results.com/soap/v1'
xmlns:nrtypens="https://apps.net-results.com/soap/v1/NRAPI.xsd"
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
This is an error in the WSDL. It appears that the "nrns" is meant to be https://apps.net-results.com/soap/v1. Note that this is the targetNamespace of the WSDL, in the definitions element.
So just add
xmlns:nrns='https://apps.net-results.com/soap/v1'
in the definitions element, and you should be fine.
Namespaces are a way to associate your elements to a particular type to avoid name conflicts. Refer here http://www.w3schools.com/xml/xml_namespaces.asp
You can pretty much anything is ??? and that should solve your problem. It needn't be any valid URL because it's never going to go that URL on internet and check its validity.
However, I suggest you get the corrected WSDL from its owner and use that else later you may end up with problems regarding namespace mismatch wasting lot of time. For time being to continue with your testing you may pretty much put anything in <wsdl:definition> tag, something like:
xmlns:nrns="http://fakeurl.com"
p.s. Play with your imagination :)
I am trying to add FBConnect to my application which includes the SBJson framework. However, when I try to compile the project I get these two errors:
Duplicate interface definition for class 'SBJsonWriter'
Duplicate interface definition for class 'SBJsonParser'
What can I do to fix this error? Thanks for any help.
Delete
#import FacebookSDK/FacebookSDK.h
In your project
I start using FacebookSDK, but then I was disappointed with it's current state and tried to use the old "FBConnect", that's how I have got the error
There are two possibilities:
you have two interfaces with the same name. Use Xcode's find in project menu option to find instances of SBJsonWriter. Then rename one of the interfaces
somehow you have managed to import the .h file twice. Check to make sure you always use #import and not #include.
A bit more info on #import/#include:
include blindly includes the file at the location of the #include statement. This means that if you #include a file twice in your .m you will get two copies of the file. Almost all traditional C #include files have something like the following bracketing all the content:
// some_file.h
#if !defined SOME_FILE_H
#define SOME_FILE_H
// entire content of #include file
#endif
he above is sometimes referrwed to as an include guard macro.
In Objective-C, if you #import a file, a check is performed by the compiler to make sure it has not already been imported. Consequently the guards are usually omitted. So if you #include a file that was supposed to be #imported, neither check will be done and you will sometimes get duplicate definitions.
I've got a C++ class I want to use which has all the code in the header file, rather than the CPP file. I'm trying to call it from an objective-C file which inherits a UIViewController class. I've renamed the file to .mm and imported the header file for the C++ file. When I compile, I keep getting a compile-time error when I try and access a method from the C++ class saying Request for member '<method>' in '<objectName>' which is of non-class type '<C++ class name>'. I did a search and it seemed that the header was usually the issue, but I've included the header in my file. What else could it be? (I can include generic code if required, but the I'm not sure if I'm allowed to show the actual code since it belongs to a third party).
The problem is likely in the declaration of the object that gives you the error, not in the header file. Sometimes the problem is hard to spot, you'll have to share some code if you can't figure it out by yourself.
I'm not a C++ coder, so this was probably an obvious mistake, but if anyone else comes across a similar problem, I simply changed my code from:
myObject.method();
to
myObject->method();
In my past applications I have been #importing into my *.h files where needed. I have not really thought much about this before as I have not had any problems, but today I spotted something that got me to thinking that maybe I should be #import-ing into my .m files and using #class where needed in the headers (.h) Can anyone shine any light on the way its supposed to be done or best practice?
gary
In any source file, import only what you need to make that individual file valid for compilation. #class is also preferable to importing another class's headers, because the less you load the less you compile.
As a rule of thumb it is fine to use #class in your header file and an #import in your .m files. You'll get an error if you do it wrong from the compiler :)
Basically, if you are only making reference to the class you want to use, but not any specifics of the class then #class is all that is required. It tells the compiler "I'm going to be using this class here - you don't need to know much about it, other than that it is valid". (The compiler then knows to reserve a pointer for it).
If you were going to be referencing any properties/methods within the class, the compiler would start complaining (as it wouldn't have enough information about the class) so in those cases it wants you to import the file (#import xxx) in order to provide the class specifics to the compiler.
Hope this helps