PC Review


Reply
Thread Tools Rating: Thread Rating: 1 votes, 1.00 average.

ByRef/Ref passing in Web Services

 
 
Sahil Malik [MVP]
Guest
Posts: n/a
 
      3rd May 2005
Okay so now I understand (surprised though) - that WebServices can indeed
pass ByRef/ref parameters. All I have to do is mark an integer parameter of
a WebMethod as "ref". Funnily enough, this is also supported per the SOAP
Spec, and from what I understand, .NET's implementation of WebServices,
donot follow the standard, but instead shimmy this behavior by working with
a strict request/response WSDL.

So my question is - If I mark an int as "ref" in a WebMethod, it seems to
work. But if I am exposing a dumb schema (non-intelligent business object),
then it doesn't work. (Dumb Schema Non Intelligent Business object example -
a class customer, with private string FirstName, encapsulated as a
property - that's it !! (Default public constructor present))

Why should this work for only Intrinsic data types? :-/ .. or is there a
trick to making it work with serialized object graphs?

- Sahil Malik [MVP]
http://codebetter.com/blogs/sahil.malik/





 
Reply With Quote
 
 
 
 
Dave
Guest
Posts: n/a
 
      3rd May 2005
> then it doesn't work. (Dumb Schema Non Intelligent Business object example - a class customer, with private string FirstName,
> encapsulated as a property - that's it !! (Default public constructor present))


You have now defined a property, not a parameter. The difference is that you cannot define a property as "ref". If, in fact, the
property Type is of a class that inherits from MarshalByRefObject, then it will be marshalled by reference.

--
Dave Sexton
dave@www..jwaonline..com
-----------------------------------------------------------------------
"Sahil Malik [MVP]" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
> Okay so now I understand (surprised though) - that WebServices can indeed pass ByRef/ref parameters. All I have to do is mark an
> integer parameter of a WebMethod as "ref". Funnily enough, this is also supported per the SOAP Spec, and from what I understand,
> .NET's implementation of WebServices, donot follow the standard, but instead shimmy this behavior by working with a strict
> request/response WSDL.
>
> So my question is - If I mark an int as "ref" in a WebMethod, it seems to work. But if I am exposing a dumb schema
> (non-intelligent business object), then it doesn't work. (Dumb Schema Non Intelligent Business object example - a class customer,
> with private string FirstName, encapsulated as a property - that's it !! (Default public constructor present))
>
> Why should this work for only Intrinsic data types? :-/ .. or is there a trick to making it work with serialized object graphs?
>
> - Sahil Malik [MVP]
> http://codebetter.com/blogs/sahil.malik/
>
>
>
>
>



 
Reply With Quote
 
Sahil Malik [MVP]
Guest
Posts: n/a
 
      3rd May 2005
Okay there have been two misunderstandings -

1. I am passing in the customer object as a PARAMETER to a WebMethod. A dumb
schema will have properties - XmlSerialization does not worry about type
info/methods.
2. Okay if I did Customer:MarshalByRefObject - that effectively should not
and will not have any difference. This is XmlSerialization/WebService, not
Remoting. And yes I know WebService is a specialized case of remoting, but
there is a big difference - XmlSerialization vs. Binary/SoapFormatter.
XmlSerialization will try and extract MarshalByRef like any other business
object - no behavior, just soapsuds like dumb metadata - anyway write up a
quick sample to find out what I'm tryin' to say.

- Sahil Malik [MVP]
http://codebetter.com/blogs/sahil.malik/



"Dave" <NOSPAM-(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>> then it doesn't work. (Dumb Schema Non Intelligent Business object
>> example - a class customer, with private string FirstName, encapsulated
>> as a property - that's it !! (Default public constructor present))

>
> You have now defined a property, not a parameter. The difference is that
> you cannot define a property as "ref". If, in fact, the property Type is
> of a class that inherits from MarshalByRefObject, then it will be
> marshalled by reference.
>
> --
> Dave Sexton
> dave@www..jwaonline..com
> -----------------------------------------------------------------------
> "Sahil Malik [MVP]" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> Okay so now I understand (surprised though) - that WebServices can indeed
>> pass ByRef/ref parameters. All I have to do is mark an integer parameter
>> of a WebMethod as "ref". Funnily enough, this is also supported per the
>> SOAP Spec, and from what I understand, .NET's implementation of
>> WebServices, donot follow the standard, but instead shimmy this behavior
>> by working with a strict request/response WSDL.
>>
>> So my question is - If I mark an int as "ref" in a WebMethod, it seems to
>> work. But if I am exposing a dumb schema (non-intelligent business
>> object), then it doesn't work. (Dumb Schema Non Intelligent Business
>> object example - a class customer, with private string FirstName,
>> encapsulated as a property - that's it !! (Default public constructor
>> present))
>>
>> Why should this work for only Intrinsic data types? :-/ .. or is there a
>> trick to making it work with serialized object graphs?
>>
>> - Sahil Malik [MVP]
>> http://codebetter.com/blogs/sahil.malik/
>>
>>
>>
>>
>>

>
>



 
Reply With Quote
 
Dave
Guest
Posts: n/a
 
      3rd May 2005
Yes, there must be some misunderstandings.

I tested it using MarshalByRefObject just to verify that I was correct.

Create a web serivce with a web method and a custom class:

public void MyClass : MarshalByRefObject
{
public string Field = "Initial Value";
}

[WebMethod]
public void ChangeValueByRef(MyClass cls)
{
cls.Field = "New Value";
}

Consume the method:

Service1 service = new Service1();
MyClass cls = new MyClass();
service.ChangeValueByRef(cls);

// outputs "New Value"
Console.WriteLine(cls.Field);

--
Dave Sexton
dave@www..jwaonline..com
-----------------------------------------------------------------------
"Sahil Malik [MVP]" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
> Okay there have been two misunderstandings -
>
> 1. I am passing in the customer object as a PARAMETER to a WebMethod. A dumb schema will have properties - XmlSerialization does
> not worry about type info/methods.
> 2. Okay if I did Customer:MarshalByRefObject - that effectively should not and will not have any difference. This is
> XmlSerialization/WebService, not Remoting. And yes I know WebService is a specialized case of remoting, but there is a big
> difference - XmlSerialization vs. Binary/SoapFormatter. XmlSerialization will try and extract MarshalByRef like any other business
> object - no behavior, just soapsuds like dumb metadata - anyway write up a quick sample to find out what I'm tryin' to say.
>
> - Sahil Malik [MVP]
> http://codebetter.com/blogs/sahil.malik/
>
>
>
> "Dave" <NOSPAM-(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
>>> then it doesn't work. (Dumb Schema Non Intelligent Business object example - a class customer, with private string FirstName,
>>> encapsulated as a property - that's it !! (Default public constructor present))

>>
>> You have now defined a property, not a parameter. The difference is that you cannot define a property as "ref". If, in fact,
>> the property Type is of a class that inherits from MarshalByRefObject, then it will be marshalled by reference.
>>
>> --
>> Dave Sexton
>> dave@www..jwaonline..com
>> -----------------------------------------------------------------------
>> "Sahil Malik [MVP]" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
>>> Okay so now I understand (surprised though) - that WebServices can indeed pass ByRef/ref parameters. All I have to do is mark an
>>> integer parameter of a WebMethod as "ref". Funnily enough, this is also supported per the SOAP Spec, and from what I understand,
>>> .NET's implementation of WebServices, donot follow the standard, but instead shimmy this behavior by working with a strict
>>> request/response WSDL.
>>>
>>> So my question is - If I mark an int as "ref" in a WebMethod, it seems to work. But if I am exposing a dumb schema
>>> (non-intelligent business object), then it doesn't work. (Dumb Schema Non Intelligent Business object example - a class
>>> customer, with private string FirstName, encapsulated as a property - that's it !! (Default public constructor present))
>>>
>>> Why should this work for only Intrinsic data types? :-/ .. or is there a trick to making it work with serialized object graphs?
>>>
>>> - Sahil Malik [MVP]
>>> http://codebetter.com/blogs/sahil.malik/
>>>
>>>
>>>
>>>
>>>

>>
>>

>
>



 
Reply With Quote
 
Brock Allen
Guest
Posts: n/a
 
      3rd May 2005
Where is this in the SOAP spec -- and don't say Section 5 encoding rules,
since that's long outdated. If it is in the modern version of the SOAP spec,
then I'd be suprised (I can't be bothered to go look). If it's not, then
I'd rephrase "WebServices can indeed pass ByRef/ref parameters" to say "The
..NET framework will map a ref param onto WebServices semantics". Just a subtle,
yet important distinction.

> So my question is - If I mark an int as "ref" in a WebMethod, it seems
> to work. But if I am exposing a dumb schema (non-intelligent business
> object), then it doesn't work. (Dumb Schema Non Intelligent Business
> object example - a class customer, with private string FirstName,
> encapsulated as a property - that's it !! (Default public constructor
> present))


I'm not sure what a "Dumb Schema" means, but my sense is that your approach
to web services is from an object mindset which is fatal. My sense is that
you also already know this, but at the sake of being redundant, I'll mention
it again. Web Services are about XML message passing. Objects and [WebMethods]
are simply a convenience afforided to you by the framework you choose to
use to implement WebServices. That framework is very good at hiding the details
of the underlying messaging framework (SOAP, WSDL, XSD, etc). And in fact
it's too good at times. My point is that the framework is so good at hiding
the real thing we're working with (XML) such that it lets you do dumb things
that you really shouldn't be doing. Sure those dumb things work if you have
..NET on both sides, but they don't make sense in a true introp scenario.
The reason is that XML Schema is how we represent the structure of the XML
we're sending across the wire, and the [WebMethods] framework infers an XSD
from your parameters' type definitions. But there are so many things you
can do with classes in .NET that don't map correctly to XSD. This is part
of the debate over contract first.

> Why should this work for only Intrinsic data types? :-/ .. or is there
> a trick to making it work with serialized object graphs?


So, this is a flawed way to think about web services. They're not objects,
the'yre XML messages.

Now, of course, the point of the framework is to make it easier to develop
web services, so you can pass objects as long as you know that the inferred
XSD is correct. [And finally, the answer I know you're looking for] The .NET
WebService framework uses the XmlSerializer to do this mapping (for the actual
object instances passed back and forth, at least). XmlSerializer is a XSD
friendly object serilization/deserilization implementation. One part of that
is that it only will access what's public because the private keyword is
a sementic specific to a .NET class (and web services aren't about passing
classes/objects). This is in contrast to the .NET remoting serilization implementation
(SoapFormatter, and BinaryFormatter). The purpose of those is to faithfully
pass objects across the network because we have .NET on both sides. This
will dig into private fields to correctly serialize all of the state so that
the object can be fully (and correctly) deserialized on the other side.

In my web service implementations I never take .NET classes meant to be used
by other .NET code and pass those pas paremeters or return values from my
webservice. I instead create "shell" classes that only hold public fields
and perhaps references to other "shell" classes. I create them in such a
way that I know they'll be serialized out correctly according to the XSD
rules. This way I'm able to utilize the .NET framework implementation of
web services that wants to map XML messages onto classes and [WebMethods].

Sorry for the long rant and aploogies if you already know all of this. I
feel like this is such a poorly understood distinction, so if this isn't
for you then perhaps for others reading it.

-Brock
DevelopMentor
http://staff.develop.com/ballen




 
Reply With Quote
 
Brock Allen
Guest
Posts: n/a
 
      3rd May 2005
> Type is of a class that inherits from MarshalByRefObject, then it will
> be marshalled by reference.


In .NET remoting, yes. But in WebServices? How do I load a proxy in a java
or a perl script web service client that when methods are invoked on that
proxy come back and call into the .NET MBRO object? It doesn't work this
way, as they are two different frameworks for doing two different things.

-Brock
DevelopMentor
http://staff.develop.com/ballen



 
Reply With Quote
 
Sahil Malik [MVP]
Guest
Posts: n/a
 
      3rd May 2005
That is what I thought too !!

- Sahil Malik [MVP]
http://codebetter.com/blogs/sahil.malik/


"Brock Allen" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>> Type is of a class that inherits from MarshalByRefObject, then it will
>> be marshalled by reference.

>
> In .NET remoting, yes. But in WebServices? How do I load a proxy in a java
> or a perl script web service client that when methods are invoked on that
> proxy come back and call into the .NET MBRO object? It doesn't work this
> way, as they are two different frameworks for doing two different things.
>
> -Brock
> DevelopMentor
> http://staff.develop.com/ballen
>
>
>



 
Reply With Quote
 
Sahil Malik [MVP]
Guest
Posts: n/a
 
      3rd May 2005
Brock -

You are shooting the messenger boy here.

I completely agree with what you're saying. Like you, I give out training to
people who might still be caught in object thinking/single program stack
thinking/,NET only non-interoperable thinking, to them and what you say
below is exactly what I'd say too.

But as you will I am sure relate to this - one important aspect of being a
good trainer is to live and understand the mistakes, so you can clearly
explain and put the pain in words, and not only explain "WHAT" is wrong to
do, but "WHY" you shouldn't do it.

Anyway, I am not yelling at you, I'm yelling with you. :-) .. but hey,
thanks for giving words to my thoughts .. I really appreciate all the time
you put into it :-)

- Sahil Malik [MVP]
http://codebetter.com/blogs/sahil.malik/



"Brock Allen" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Where is this in the SOAP spec -- and don't say Section 5 encoding rules,
> since that's long outdated. If it is in the modern version of the SOAP
> spec, then I'd be suprised (I can't be bothered to go look). If it's not,
> then I'd rephrase "WebServices can indeed pass ByRef/ref parameters" to
> say "The .NET framework will map a ref param onto WebServices semantics".
> Just a subtle, yet important distinction.
>
>> So my question is - If I mark an int as "ref" in a WebMethod, it seems
>> to work. But if I am exposing a dumb schema (non-intelligent business
>> object), then it doesn't work. (Dumb Schema Non Intelligent Business
>> object example - a class customer, with private string FirstName,
>> encapsulated as a property - that's it !! (Default public constructor
>> present))

>
> I'm not sure what a "Dumb Schema" means, but my sense is that your
> approach to web services is from an object mindset which is fatal. My
> sense is that you also already know this, but at the sake of being
> redundant, I'll mention it again. Web Services are about XML message
> passing. Objects and [WebMethods] are simply a convenience afforided to
> you by the framework you choose to use to implement WebServices. That
> framework is very good at hiding the details of the underlying messaging
> framework (SOAP, WSDL, XSD, etc). And in fact it's too good at times. My
> point is that the framework is so good at hiding the real thing we're
> working with (XML) such that it lets you do dumb things that you really
> shouldn't be doing. Sure those dumb things work if you have .NET on both
> sides, but they don't make sense in a true introp scenario. The reason is
> that XML Schema is how we represent the structure of the XML we're sending
> across the wire, and the [WebMethods] framework infers an XSD from your
> parameters' type definitions. But there are so many things you can do with
> classes in .NET that don't map correctly to XSD. This is part of the
> debate over contract first.
>
>> Why should this work for only Intrinsic data types? :-/ .. or is there
>> a trick to making it work with serialized object graphs?

>
> So, this is a flawed way to think about web services. They're not objects,
> the'yre XML messages.
>
> Now, of course, the point of the framework is to make it easier to develop
> web services, so you can pass objects as long as you know that the
> inferred XSD is correct. [And finally, the answer I know you're looking
> for] The .NET WebService framework uses the XmlSerializer to do this
> mapping (for the actual object instances passed back and forth, at least).
> XmlSerializer is a XSD friendly object serilization/deserilization
> implementation. One part of that is that it only will access what's public
> because the private keyword is a sementic specific to a .NET class (and
> web services aren't about passing classes/objects). This is in contrast to
> the .NET remoting serilization implementation (SoapFormatter, and
> BinaryFormatter). The purpose of those is to faithfully pass objects
> across the network because we have .NET on both sides. This will dig into
> private fields to correctly serialize all of the state so that the object
> can be fully (and correctly) deserialized on the other side.
>
> In my web service implementations I never take .NET classes meant to be
> used by other .NET code and pass those pas paremeters or return values
> from my webservice. I instead create "shell" classes that only hold public
> fields and perhaps references to other "shell" classes. I create them in
> such a way that I know they'll be serialized out correctly according to
> the XSD rules. This way I'm able to utilize the .NET framework
> implementation of web services that wants to map XML messages onto classes
> and [WebMethods].
>
> Sorry for the long rant and aploogies if you already know all of this. I
> feel like this is such a poorly understood distinction, so if this isn't
> for you then perhaps for others reading it.
>
> -Brock
> DevelopMentor
> http://staff.develop.com/ballen
>
>
>
>
>



 
Reply With Quote
 
Sahil Malik [MVP]
Guest
Posts: n/a
 
      3rd May 2005
Okay here is a more detailed answer - but don't rant at me, I am just trying
to discuss with you.

http://www.w3.org/TR/2000/NOTE-SOAP-...#_Toc478383533

<--- 7.1, bullet #5 - says .."... method response is viewed as a single
struct containing an accessor for the return value and each [out] or
[in/out] parameter. "

Okay what I meant by a dumb schema was - here is an example -

public class Customer {
public Customer() {}
public string FirstName { get {..} set {...} }
}

Basically, XmlSerializer in it's serialization and deserialization - will
not loose any nature of the object - because the object itself contains no
logic inside, just a dead - data object map.

No I am not thinking in Object terms, if I were, I'd make this guy inherit
from a Person, and Person would have a constraint that a person can have
only two legs and no more. That would not be extractable via
soapsuds/XmlSerialization - thus doesn't fall into the WebService
philosophy.

Finally ---

> > Why should this work for only Intrinsic data types? :-/ .. or is there
> > a trick to making it work with serialized object graphs?

>
> So, this is a flawed way to think about web services. They're not objects,
> the'yre XML messages.


Agreed. but the above object is serialized to Xml, sent over, and
deserialized back to yourproject.webreferencename.object - which has no
logic inside, but a dumb object !! So true it is about message passing, but
I could pass in a schema. Yes sir, this is still schema headed thinking, and
not object headed thinking. I mean, a webservice isn't limited to passing in
only Ints/doubles and other scalar types. Even the Customer object I
specified is readable through a non .NET web service because (magic words
follow) - "The proxy object is created via. the information in the WSDL".

So ... in short, I agree with your arguments,

Now back to the question - How do I make ref type work with non scalar data
types? (Not that I'd ever want to, but for academic reasons .. How?)

- Sahil Malik [MVP]
http://codebetter.com/blogs/sahil.malik/



"Brock Allen" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Where is this in the SOAP spec -- and don't say Section 5 encoding rules,
> since that's long outdated. If it is in the modern version of the SOAP

spec,
> then I'd be suprised (I can't be bothered to go look). If it's not, then
> I'd rephrase "WebServices can indeed pass ByRef/ref parameters" to say

"The
> .NET framework will map a ref param onto WebServices semantics". Just a

subtle,
> yet important distinction.
>
> > So my question is - If I mark an int as "ref" in a WebMethod, it seems
> > to work. But if I am exposing a dumb schema (non-intelligent business
> > object), then it doesn't work. (Dumb Schema Non Intelligent Business
> > object example - a class customer, with private string FirstName,
> > encapsulated as a property - that's it !! (Default public constructor
> > present))

>
> I'm not sure what a "Dumb Schema" means, but my sense is that your

approach
> to web services is from an object mindset which is fatal. My sense is that
> you also already know this, but at the sake of being redundant, I'll

mention
> it again. Web Services are about XML message passing. Objects and

[WebMethods]
> are simply a convenience afforided to you by the framework you choose to
> use to implement WebServices. That framework is very good at hiding the

details
> of the underlying messaging framework (SOAP, WSDL, XSD, etc). And in fact
> it's too good at times. My point is that the framework is so good at

hiding
> the real thing we're working with (XML) such that it lets you do dumb

things
> that you really shouldn't be doing. Sure those dumb things work if you

have
> .NET on both sides, but they don't make sense in a true introp scenario.
> The reason is that XML Schema is how we represent the structure of the XML
> we're sending across the wire, and the [WebMethods] framework infers an

XSD
> from your parameters' type definitions. But there are so many things you
> can do with classes in .NET that don't map correctly to XSD. This is part
> of the debate over contract first.
>
> > Why should this work for only Intrinsic data types? :-/ .. or is there
> > a trick to making it work with serialized object graphs?

>
> So, this is a flawed way to think about web services. They're not objects,
> the'yre XML messages.
>
> Now, of course, the point of the framework is to make it easier to develop
> web services, so you can pass objects as long as you know that the

inferred
> XSD is correct. [And finally, the answer I know you're looking for] The

..NET
> WebService framework uses the XmlSerializer to do this mapping (for the

actual
> object instances passed back and forth, at least). XmlSerializer is a XSD
> friendly object serilization/deserilization implementation. One part of

that
> is that it only will access what's public because the private keyword is
> a sementic specific to a .NET class (and web services aren't about passing
> classes/objects). This is in contrast to the .NET remoting serilization

implementation
> (SoapFormatter, and BinaryFormatter). The purpose of those is to

faithfully
> pass objects across the network because we have .NET on both sides. This
> will dig into private fields to correctly serialize all of the state so

that
> the object can be fully (and correctly) deserialized on the other side.
>
> In my web service implementations I never take .NET classes meant to be

used
> by other .NET code and pass those pas paremeters or return values from my
> webservice. I instead create "shell" classes that only hold public fields
> and perhaps references to other "shell" classes. I create them in such a
> way that I know they'll be serialized out correctly according to the XSD
> rules. This way I'm able to utilize the .NET framework implementation of
> web services that wants to map XML messages onto classes and [WebMethods].
>
> Sorry for the long rant and aploogies if you already know all of this. I
> feel like this is such a poorly understood distinction, so if this isn't
> for you then perhaps for others reading it.
>
> -Brock
> DevelopMentor
> http://staff.develop.com/ballen
>
>
>
>
>



 
Reply With Quote
 
Brock Allen
Guest
Posts: n/a
 
      3rd May 2005
> Now back to the question - How do I make ref type work with non scalar
> data types? (Not that I'd ever want to, but for academic reasons ..
> How?)


This works for me:

public class Foo
{
public int xoxo;
}

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1, EmitConformanceClaims
= true)]
public class WebService : System.Web.Services.WebService
{
[WebMethod]
public void HelloWorld(ref Foo param)
{
}
}

-Brock
DevelopMentor
http://staff.develop.com/ballen




 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ByRef/Ref passing in Web Services Sahil Malik [MVP] Microsoft C# .NET 4 5th May 2005 03:01 AM
Passing ByRef or ByVal Just Me Microsoft VB .NET 3 20th Jul 2004 02:44 PM
ByRef not passing address Ian Stanborough Microsoft Excel Programming 3 30th Oct 2003 01:30 PM
Passing ByRef and ByVal VB.NET Andy Read Microsoft Dot NET 4 25th Aug 2003 07:16 PM
passing arguments byref in VBA Jim Dalrymple Microsoft Access VBA Modules 5 25th Jul 2003 05:46 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 04:45 PM.