Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / Web Services / August 2004

Tip: Looking for answers? Try searching our database.

Passing Inherited types to a web service method

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Paul Michaud - 11 Aug 2004 03:39 GMT
Consider the following:

Class A
{
...
}

Class B:A
{
...
}

Class C:A
{
...
}

Now consider a webservice with the following method

[WebMethod]
public int doSomething(ref A theAInstance)
{
...
}

When I create an application which tries to call the doSomething
method as follows:

status=doSomething(ref instanceOfB);

I get the following error:

cannot convert from 'ref B' to 'ref A'

According to all the docs I have on .Net and webservices, this should
work.  I have tried to use xmlinclude to declare the inherited types
in both the definition of A and at the method level (I have seen
people suggest both) and still no go.  Are we saying that it is
impossible to pass an inherited type by ref in a web service.  If not
any guidance or sample code that would work is greatly appreciated.

Paul
Paul Michaud - 11 Aug 2004 04:28 GMT
To elaborate I also tried the following:

[XmlInclude(typeof(B))]
[XmlInclude(typeof(C))]
Class A
{
...
}

and

[XmlInclude(typeof(B))]
[XmlInclude(typeof(C))]
[WebMethod]
public int doSomething(ref A theAInstance)
{
...
}

Paul

> Consider the following:
>
[quoted text clipped - 38 lines]
>
> Paul
Jeffrey Hasan - 13 Aug 2004 00:32 GMT
This is a very interesting issue! There are no restrictions on passing
custom types to Web services, by VALUE, including inherited types, such as
your B : A. I wrote some basic test code to verify this. In order for this
to work, the Web service and the client must have a common understanding of
the data types. You need to make sure that the type definitions are broken
out into a separate referanceable file, or type definition assembly, with a
dedicated namespace, so that you can drop it into whatever projects need it.
In your case, the Web service and the client. Then, when you set the Web
service calls, you can do so using these qualified types. (And of course, in
Web services terms what you are doing here is referencing the same
XSD-qualified type). For example:

namespace WSTypes
{
public class A {}
public class B : A {}
}

I think you already know this, and have something like this implemented. Now
regarding your use of "ref". This is the cause of your issue. If you define
a Web method that accepts A by VALUE, then you can pass in either A or B.
However, if your Web method accepts A by REF then you can only pass in A.
The reason appears to have to do with the way data types are deserialized on
the receiving end. Call it a bug or a known issue, but it is clearly
something that does not work as it should.

So what I would do is to write your Web methods to accept A and then return
B, as in:

[WebMethod]
public WSTypes.B doSomething(ref WSTypes.A objA)
{

}

This should be an acceptable workaround. Hope this helps -

Jeffrey Hasan, MCSD
President, Bluestone Partners, Inc.
-----------------------------------------------
Author of: Expert SOA in C# Using WSE 2.0 (APress, 2004)
http://www.bluestonepartners.com/soa.aspx

> To elaborate I also tried the following:
>
[quoted text clipped - 59 lines]
> >
> > Paul
Paul Michaud - 13 Aug 2004 14:13 GMT
Hi Jeffrey,
   Thanks for the reply. The reason I don't want to pass the variable back
through the return type, is that I always use the return for error codes.  I
think I have figured out the issue.  Consider the following:

A,B, etc defined as below.

Now call
status=doSomething(ref instanceOfB);

This doesn't work because of the issue you mentioned below.

so create a new variable called tempA and point it at instanceOfB (or so we
might think)
A tempA=(A)instanceOfB;

now call the function with tempA.

status=doSomething(ref instanceOfB);

Here is what I have found to have happened.
1) tempA comes back knowing its of type B (or at least when you do a watch
it has the additional attributes present in B and not in A in a substructure
, which by the way manifests differently on either side of the web service
call which is odd, but it does appear to have worked)
2) if I now cast tempA to type B and access the B specific properties it
works fine.  All  the data is there correctly.
3) Even though tempA was set to be equal to instanceOfB when the function
returns, tempA and instanceOfB are no longer the same insance, they are two
different instances after the de-serialization of tempA.  Thus the original
variable instanceOfB is not filled unless you set
instanceOfB=tempA after the call.

The real issue is that according to the web service spec, I should be able
to pass instanceOfB directly and it should work.  The fact that I can't
seems to be specifically a .Net bug.  The other possibility is that there
may be some settings to export the class hierarchy through the web service
definition so that .Net knows B is a type of A and thus doesn't throw the
compile error (I do have a using statement with an interface dll which
com=ntains the class hierarchy but that doesn't do it).  But if there is
something like that I haven't found it yet.  I have tried the settings I
mentioned before which I thought was supposed to work but no go.

If anyone knows how to accomplish this I would appreciate it. I have spoken
to a number of others about this and they have had the same problem and
haven't found a decent work around yet.
Paul Michaud

> This is a very interesting issue! There are no restrictions on passing
> custom types to Web services, by VALUE, including inherited types, such as
[quoted text clipped - 102 lines]
> > >
> > > Paul

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.