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 / March 2008

Tip: Looking for answers? Try searching our database.

How to return a user-defined data type object from a webservice?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
nano2k - 29 Feb 2008 20:57 GMT
Hi

In my solution I have 3 projects:

1. A class library. Let's name it CL (let's also name the namespace as
"CL").
This class library defines a type like this:

[SerializableAttribute()]
public class Person {
 //default constructor
 private string m_firstName;
 private string m_lastName;

 public string FirstName {
   get { return m_firstName; }
   set {m_firstName = value; }
 }

 public string LastName {
   get { return m_lastName; }
   set {m_lastName = value; }
 }
}

2. A webservice that references CL (described above).
The webservice defines and implements a web method like:

[WebMethod]
public CL.Person GetPerson() {
 CL.Person person = new Person();
 //read person from database
 return person;
}

3. A client winforms application that references the class library
decribed above, instantiates a proxy to the webservice and calls the
web method GetPerson like this:

private void FetchPerson() {
 //proxy gets created
 CL.Person person = proxy.GetPerson();
}

The compiler will generate a compiler error like this:
Cannot implicitly convert type 'WinFormClientApp.MyWebService.Person'
to 'CL.Person'

Where do I go wrong? How to "transport" more complex objects between
client and the webserver.
I understand how serialization works and I think the serialization
should implicitly work when returning such complex types. Maybe I
missed something.
Should I explicitly use soap serialization and deserialization? Hope
not.

Please help.
Thanks.
nano2k - 29 Feb 2008 21:04 GMT
> Hi
>
[quoted text clipped - 57 lines]
> Please help.
> Thanks.

BTW, I am using dotnet 2.0 with VS 2005.
John Saunders [MVP] - 02 Mar 2008 01:07 GMT
> Hi
>
> In my solution I have 3 projects:
>
> 1. A class library. Let's name it CL (let's also name the namespace as
> "CL").
...
> Where do I go wrong? How to "transport" more complex objects between
> client and the webserver.
[quoted text clipped - 3 lines]
> Should I explicitly use soap serialization and deserialization? Hope
> not.

You went wrong in not understanding web services. Web Services don't
"transport" complex types. They transport XML. In order to keep you from
having to deal with XML, .NET allows the service to "return" a complex type,
CL.Person. .NET then takes care of serializing that complex type into XML.
On the client side, in order to keep the client from having to deal with
XML, .NET creates proxy classes. In particular, it creates a
WebReferenceName.Person class. That is whtat the proxy GetPerson method
returns, not CL.Person.

So, long story short, your client should never reference the class library
"CL".
Signature

--------------------------------------------------------------------------------
John Saunders | MVP - Windows Server System - Connected System Developer

nano2k - 02 Mar 2008 06:44 GMT
Thanks, John.

On 2 Mar, 03:07, "John Saunders [MVP]" <john.saunders at trizetto.com>
wrote:

> > Hi
>
[quoted text clipped - 25 lines]
> ---------------------------------------------------------------------------­-----
> John Saunders | MVP - Windows Server System - Connected System Developer
nano2k - 02 Mar 2008 07:40 GMT
Anyway,

Passing DataSet or XmlNode objects works by itself.
How can I enable my Person class to act like the above ones?

Thanks.

> Thanks, John.
>
[quoted text clipped - 36 lines]
>
> - Afişare text în citat -
John Saunders [MVP] - 03 Mar 2008 12:34 GMT
Anyway,

Passing DataSet or XmlNode objects works by itself.
How can I enable my Person class to act like the above ones?

=========
You don't want to. Really.
Signature

--------------------------------------------------------------------------------
John Saunders | MVP - Windows Server System - Connected System Developer

nano2k - 04 Mar 2008 19:09 GMT
On 3 Mar, 14:34, "John Saunders [MVP]" <john.saunders at trizetto.com>
wrote:
> Anyway,
>
[quoted text clipped - 6 lines]
> ---------------------------------------------------------------------------­-----
> John Saunders | MVP - Windows Server System - Connected System Developer

Sorry, but why?
Just for the record.
John Saunders [MVP] - 04 Mar 2008 22:46 GMT
On 3 Mar, 14:34, "John Saunders [MVP]" <john.saunders at trizetto.com>
wrote:
> "nano2k" <adrian.rot...@ikonsoft.ro> wrote in message
>
[quoted text clipped - 9 lines]
> ---------------------------------------------------------------------------­-----
> John Saunders | MVP - Windows Server System - Connected System Developer

Sorry, but why?
Just for the record.
=
I pretty much told you why before. It's just not how Web Services works.

The paradigm of Web Services is all about interoperability between client
and server by using industry-standard protocols (HTTP) and data formats
(XML). You are asking how you can use the above to pass data specific to a
particular platform (Microsoft .NET). There is no provision for that in the
Web Services standards. If you read those standards, you'll find mention of
the use of standards (XML Schema) to describe the structure of the data to
be exchanged. Nowhere in any of those standards is there an ability for you
to specify a particular data type from a particular platform.

This is in contrast to .NET Remoting, which is platform-specific, and which
actually transmits the full typename and assembly name of the types of the
data being transferred. This permits the client to receive instances of the
precise type sent by the server. There is no provision for anything like
this in Web Services.

Now, I'm only just recently getting up to speed on WCF, but it looks like
when you create a Service Reference (the WCF equivalent of a Web Reference),
you have the ability to tell WCF to try to reuse datatypes if the types are
declared in particular assemblies. This may give you what you're looking
for, as long as you are in a controlled environment where you can be certain
that the type that WCF will choose for you is compatible with the type being
sent by the server. An example of such an environment is when the server and
all of its clients are in the same .NET solution. Tihs may be acceptable for
"internal" web services, which are only ever meant to be used by well-known
clients. It cannot work in the general case.
Signature

--------------------------------------------------------------------------------
John Saunders | MVP - Windows Server System - Connected System Developer

nano2k - 05 Mar 2008 15:19 GMT
On 5 Mar, 00:46, "John Saunders [MVP]" <john.saunders at trizetto.com>
wrote:

> On 3 Mar, 14:34, "John Saunders [MVP]" <john.saunders at trizetto.com>
> wrote:
[quoted text clipped - 46 lines]
> ---------------------------------------------------------------------------­-----
> John Saunders | MVP - Windows Server System - Connected System Developer

Thanks John.
I understand and aggree entirely.
But my app is ment to work ONLY on .NET platforms. It is not a public
web site or smtg like that.
It's an "internal" application for a company that will use the app
inside its own VPN.
More than that, I'm being asked to secure the entire system so that
the webservice will only work with the designated client (also
developed by me).

So I find myself in this particular case, not in the general case. I
assure you I understand how interoperatibility works and its demands.

Anyway, your input was very good for me, but what do you say about my
particular situation? Creating standard XML schemas for each type I
want to "transport" would be a waiste of time, as I am 100% SURE my
webservice will only be accessible from a .NET client.

PS: I should have been more specific on this on my first post, my bad.
John Saunders [MVP] - 05 Mar 2008 21:29 GMT
Thanks John.
I understand and aggree entirely.
But my app is ment to work ONLY on .NET platforms. It is not a public
web site or smtg like that.
It's an "internal" application for a company that will use the app
inside its own VPN.
More than that, I'm being asked to secure the entire system so that
the webservice will only work with the designated client (also
developed by me).

So I find myself in this particular case, not in the general case. I
assure you I understand how interoperatibility works and its demands.

Anyway, your input was very good for me, but what do you say about my
particular situation? Creating standard XML schemas for each type I
want to "transport" would be a waiste of time, as I am 100% SURE my
webservice will only be accessible from a .NET client.

PS: I should have been more specific on this on my first post, my bad.
==========

If you're doing .NET to .NET, then you shouldn't be using Web Services - you
should be using .NET Remoting, or WCF with the NetDataContractSerializer.
These cover the case I mentioned, where it's important to be using the
correct version of the correct type. They both communicate the actual .NET
type name across the channel.

If, for some political reason you feel you must stick to ASMX web services,
then you can do something like have a translation layer than receives the
proxy type, then uses it to fill in an instance of the "real" type.
Signature

--------------------------------------------------------------------------------
John Saunders | MVP - Windows Server System - Connected System Developer

nano2k - 07 Mar 2008 14:36 GMT
Thanks John and Brad

John,
Never dealed with .NET Remoting or WCF.
Any good and easy to digest resources on these?
Thanks.

On 5 Mar, 23:29, "John Saunders [MVP]" <john.saunders at trizetto.com>
wrote:
> Thanks John.
> I understand and aggree entirely.
[quoted text clipped - 29 lines]
> ---------------------------------------------------------------------------­-----
> John Saunders | MVP - Windows Server System - Connected System Developer
John Saunders [MVP] - 07 Mar 2008 15:00 GMT
Thanks John and Brad

John,
Never dealed with .NET Remoting or WCF.
Any good and easy to digest resources on these?
Thanks.
=============
I have been working seriously with WCF only for the past few weeks.
Nonetheless, I'm willing to make a suggestion.

Try the Web Services Software Factory: Modeling Edition  at
http://www.codeplex.com/servicefactory. This is what I've been reviewing for
the past week or so, and have mostly decided that I'll recommend it as the
way for my company to go forward with web services.

As it relates to your situation, I think it will be helpful. WCF makes a
strong distinction between the types sent out on the wire, and the types
used in the Business Logic Layer, and the Data Access Layer below that.
WSSF:ME goes further by requiring you to design your wire formats in an
abstract way, and then by helping you create translation methods for
translating between the layers. At the same time, it permits the client and
server both to work with these "data contract" types in useful ways. You can
specify, for instance, that the server will treat a particular collection as
an array, but the client will treat it as a List<T>, or a Dictionary<string,
T>.

Give it a look.
Signature

--------------------------------------------------------------------------------
John Saunders | MVP - Windows Server System - Connected System Developer

Bradley Plett - 05 Mar 2008 22:46 GMT
What John is saying is all true, but it's a bit of an ivory tower
approach.  Sometimes we developers have to bend the rules because it's
the easiest way to get the job done!

Anyway, I'm guessing that you have shared code between your server and
your client (probably using the same class code, shared in VSS).  If
that's the case, what you're up against is simply the fact that the
object coming from the server via the web service is in a different
namespace from the object you want to use in your client.  There are a
variety of ways of getting around this problem.  For example, you can
use reflection and generics to change the namespace of the object in
question.  Here's a code sample that will simply copy everything from
one object to another, assuming all their public properties are
identical:

// the idea for this came from
http://www.eggheadcafe.com/tutorials/aspnet/a4264125-fcb0-4757-9d78-ff541dfbcb56
/net-reflection--copy-cl.aspx

private static T SetProperties<T, U>(U fromRecord, T toRecord)
{
 foreach (PropertyInfo fromField in
fromRecord.GetType().GetProperties())
 {
   if (fromField.Name != "Id")
   {
     foreach (PropertyInfo toField in
toRecord.GetType().GetProperties())
     {
       if (fromField.Name == toField.Name)
       {
         toField.SetValue(toRecord, fromField.GetValue(fromRecord,
null), null);
         break;
       }
     }
   }
 }
 return toRecord;
}

Hope that helps!
Brad.

>On 5 Mar, 00:46, "John Saunders [MVP]" <john.saunders at trizetto.com>
>wrote:
[quoted text clipped - 69 lines]
>
>PS: I should have been more specific on this on my first post, my bad.
John Saunders [MVP] - 06 Mar 2008 03:11 GMT
> What John is saying is all true, but it's a bit of an ivory tower
> approach.  Sometimes we developers have to bend the rules because it's
[quoted text clipped - 10 lines]
> one object to another, assuming all their public properties are
> identical:

Sorry, Bradley, you're wrong. It's not that the classes are in different
namespaces. They're different classes that happen to have a lot of names in
common. Try returning a custom type that has a non-default constructor, or
methods, or indexers. None of them will show up in the proxy classes because
none of them are described by XML Schema or WSDL.

Remember: they're _proxy_ classes. They are stand-ins for the real classes,
which never leave the server to travel over the wire. They only exist in
order to stand as proxy for the real classes, handling serialization and
deserialization.
Signature

--------------------------------------------------------------------------------
John Saunders | MVP - Windows Server System - Connected System Developer

Bradley Plett - 06 Mar 2008 07:17 GMT
Yes, I understand that they're different classes and different
objects.  That is, after all, the implication of different namespaces.
I also understand that there can be issues around the constructor and
any hidden data, but pragmatically the solution I suggested will
handle the majority of the situations common programmers deal with
between server-side and client-side objects.  :-)

Sure, remoting might be a preferable solution to maintain the full,
true object, but sometimes remoting is overkill and I think sometimes
we tend to over-think/over-analyze and ignore simple solutions which
may be less elegant and less pure, but do the job.

Brad.

>> What John is saying is all true, but it's a bit of an ivory tower
>> approach.  Sometimes we developers have to bend the rules because it's
[quoted text clipped - 21 lines]
>order to stand as proxy for the real classes, handling serialization and
>deserialization.
John Saunders [MVP] - 06 Mar 2008 15:49 GMT
> Yes, I understand that they're different classes and different
> objects.  That is, after all, the implication of different namespaces.
[quoted text clipped - 7 lines]
> we tend to over-think/over-analyze and ignore simple solutions which
> may be less elegant and less pure, but do the job.

Brad, in answering newsgroup and forum posts on this topic, I have found
many people who do expect the code they wrote in their server-side classes
to appear on the client side. In my opinion, that's because .NET makes it so
easy to call a "web method". After all, it's a _method_, isn't it?

The problem is that this totally obscures what's actually happening, so many
people never even learn that there is something different happening at all.
I recommend naming web references with the word "Proxy" in the name, so
that, maybe, some new developer will at least wonder "proxy for what"? It
would also make it easier for me, when they ask "where's my indexer", to
answer, "remember, it's only a proxy class". They could then say, "oh, so
_that's_ why it's called Proxy".

;-)

Also, Brad, if you're going to suggest that people modify the proxy class,
you should remind them that the class will be overwritten whenever "Update
Web Reference" is used. For that reason, I _never_ suggest modifying
generated code.
Signature

--------------------------------------------------------------------------------
John Saunders | MVP - Windows Server System - Connected System Developer

Bradley Plett - 06 Mar 2008 16:40 GMT
Good point - it is worth understanding, that's for sure!

The sample I gave was not intended to modify the proxy class.  I never
do that either, since regeneration, for me, is a fairly common task.
The sample I gave was intended either in an inherited class or as a
utility function.

Brad.

>> Yes, I understand that they're different classes and different
>> objects.  That is, after all, the implication of different namespaces.
[quoted text clipped - 27 lines]
>Web Reference" is used. For that reason, I _never_ suggest modifying
>generated code.
Relaxin - 09 Mar 2008 14:05 GMT
> Sure, remoting might be a preferable solution to maintain the full,
> true object, but sometimes remoting is overkill and I think sometimes
> we tend to over-think/over-analyze and ignore simple solutions which
> may be less elegant and less pure, but do the job.
>
> Brad.

That was said beautifully!!

Rate this thread:







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.