Sending XML File via SOAP Web services

1,434 views
Skip to first unread message

Andy

unread,
Aug 17, 2009, 6:10:10 AM8/17/09
to intersystems.public.cache
Hi there,

I have written a SOAP web service method that reads an xml file that
exists on the server and imports the contents of this file into a
persistent object.

What I would like to do is to send this xml file from the client to
the server when the web method is invoked by the client. So on the
client application (that accesses the SOAP web service remotely) I
would like to invoke the method passing in the xml file to send. For
example: client.SendXMLFile("C:/test.xml")

The problem I am having is that the above does not send the file but
just sends the location of the file. Therefore the web method thinks
the file is on its server not the client's server.

Is it possible to send the contents of an xml file via SOAP by
specifying the file name?

Thanks

Andy

Mike Henderson

unread,
Aug 17, 2009, 9:34:34 AM8/17/09
to intersystems...@googlegroups.com
There are 2 ways you could approach this. First, you could have the
web-service expect a %BinaryStream that contains the XML markup you want to
convert:
Method SendXMLFile(XMLFile As %GlobalBinaryStream) [WebMethod] {
// read in xml, validate it and convert to persistent objects
}
This is a simple approach and is easiest for the client to implement -- it
only has to write the XML file as base-64. However, you will have to do your
own XML validation.

The second, and arguably the better way, would be to make the persistent
objects XML enabled and just pass the object to the web-method. This
leverages all the SOAP/XML logic that Cache has built in, but makes the WSDL
for the service more complicated and thus requires more work on the client.
Method SendData(Data as MyPersistentObject) [WebMethod] {
// logic and a 'Do Data.%Save(1)' to put it in the database
}
This method is definitely preferable if you have control over the client and
the client is a Cache %SOAP.WebClient -- you can reuse the persistent class
definition on both ends.

--Mike
J2 Interactive

Andy

unread,
Aug 18, 2009, 4:32:48 AM8/18/09
to intersystems.public.cache
Thanks Mike,

I do not have control over the client and the client is written
in .NET (WCF). Therefore I am assuming that I will need to go with the
first option (BinaryStream)?

However if a .NET client created the same objects that I have defined
in cache, could these be passed to the web method and would cache
recognise them?

Mike Henderson

unread,
Aug 18, 2009, 9:53:01 AM8/18/09
to intersystems...@googlegroups.com
A good question, but I've never worked with the .NET SOAP framework. Since
Cache web services provide a valid WSDL, I assume that .NET can read that
WSDL and generate the appropriate code to call the web service.

Hopefully someone here who has worked with .NET SOAP with Cache will be able
to give you a more guidance.

--Mike
J2 Interactive

-----Original Message-----
From: intersystems...@googlegroups.com
[mailto:intersystems...@googlegroups.com] On Behalf Of Andy
Sent: Tuesday, August 18, 2009 3:33 AM
To: intersystems.public.cache

Andy

unread,
Aug 18, 2009, 11:25:51 AM8/18/09
to intersystems.public.cache
Thanks Mike..

On another note, do you know about WS-Security User Authentication?

I am using cache 2007 and the documentation on this area is a little
vague.

I understand that the web client must invoke the WSSecurityLogin
method before invoking the web method but would this still be the case
if the web client is a .NET application? And in my Web service, where
and how would I define the user name and password that the web client
would need to know?

Andy




wolfkoelling

unread,
Aug 19, 2009, 12:13:39 PM8/19/09
to intersystems.public.cache
You don't define a username/password in your web service, this is
handled by Caché Security. You are after a valid Caché user which has
the privilege to run your csp application (which is what a web service
is).

In .Net you don't call the WSSecurityLogin method. Instead you need
to add username and password to the SOAP header. The resulting soap
request will look exactly as if you were using a Caché web service
client using that method.

If you want plain text username/password, you need something like this
(in C#):

// web service enhancements
using Microsoft.Web.Services3.Security.Tokens;

//create security token
UsernameToken userToken = new UsernameToken("myUser","myPassword",
PasswordOption.SendPlainText);

// create instance of web service
MyWebServiceRef wsProxy = new MyWebserviceRef();

wsProxy.PreAuthenticate = true;

wsProxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

//get soapcontext associated with soap request
SoapContext requestContext = wsProxy.RequestSoapContext;

//time to live
requestContext.Security.Timestamp.TtlInSeconds = 60;

// add security token to header
requestContext.Security.Tokens.Add(userToken);

// now you can just call the methods on the web service

I hope this will point you in the right direction.

Wolf Koelling
Slaughter and May

Andy

unread,
Sep 2, 2009, 6:32:51 AM9/2/09
to intersystems.public.cache
Thanks for your help,

I have created a valid Caché user which has the privilege to run the
csp application (web service). I have also changed the 'Enable/
Disable Authentication allowed' (Under CSP applications) to Password
from Authenticated.

I understand that in .Net I need to add username and password to the
SOAP header. However before I can do this I would need to add a
Service Reference (in the .Net Project) to the Web service. But when
trying to do so I get this error shown below. The reason for this is
because the Cache login page is being returned instead, this is
because it seems to need a username and password to even add a service
reference in a .Net project.

Is there a way to add the Username/password when adding a web
reference?

Thanks

Andy

The HTML document does not contain Web service discovery information.
Metadata contains a reference that cannot be resolved: 'http://
192.168.218.4/csp/test/Test.MyService.cls?WSDL'.
The content type text/html; charset=ISO-8859-1 of the response message
does not match the content type of the binding (application/soap+xml;
charset=utf-8). If using a custom encoder, be sure that the
IsContentTypeSupported method is implemented properly. The first 1024
bytes of the response were: '<html><head>
<title>Login CACHE2007</title>

<link rel="stylesheet" type="text/css" href="/csp/sys/
intersystems.css">
<script language="javascript">
// called when page is loaded
function pageLoad()
{
// see if we can give focus to the UserName field:
if (self.document.Login && self.document.Login.CacheUserName) {
self.document.Login.CacheUserName.focus();
self.document.Login.CacheUserName.select();
}
return true;
}
</script>
</head>
<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"
onload="pageLoad();">


<table width="100%" border="0" cellpadding="0" cellspacing="0"
style="background: red; margin:0px;">
<tr>
<td nowrap bgcolor="#FFFAE7" valign="top" align="left"><a
target="_top" href="http://www.intersystems.com/index.html"><img src="/
csp/sys/images/logo-topl-intersystems.gif" border="0"></a></td>
<td nowrap bgcolor="#FFFAE7" valign="top" align="left">
<div class="wizardltlabel" style="margin-top:10px;"><span
style="font-size:8pt; padding-'.
If the service is defined in the current solution, try building the
solution and adding the service reference again.

wolfkoelling

unread,
Sep 4, 2009, 6:10:15 AM9/4/09
to intersystems.public.cache
Yes, I remember now that this caught us out as well. Never got to the
bottom of this (as we abandoned the SOAP approach for this project
soon after) but there are two workarounds:

1. Export the WSDL into a text file and read this into Visual Studio
2. Temporarily set Authentication to Unauthenticated in your csp
application. This allows Studio to set the reference. Then change
authentication back to Password.

Wolf
Message has been deleted

Meetu Sharma

unread,
Aug 8, 2014, 7:46:20 AM8/8/14
to intersystems...@googlegroups.com
Hi Andy,

Good Morning!

I am trying to implement something similar but I need the data to be converted to json. Can you please give me your code as a refernce? It would be a great help.

Thanks,

Meetu
Reply all
Reply to author
Forward
0 new messages