468,168 Members | 1,521 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,168 developers. It's quick & easy.

webmethod returning interface or receiving an interface parameter

LS
Can a WebMethod return an Interface type?
Can we pass an interface parameter ?

Example :

public interface IEntity
{
long Id { get; set; }
string Name { get; set; }
}

[WebMethod]
public IEntity Fetch(long entityKey)
{
...
}

[WebMethod]
public bool Save(IEntity entity)
{
...
}

Thanks for your reply
Nov 21 '05 #1
5 9980
LS wrote:
Can a WebMethod return an Interface type?
Can we pass an interface parameter ?


The short answer is "no". You'll get an error just trying to generate any kind of service description along the lines of:

Cannot serialize interface TestWebService.IFoo.

If you think about it, interfaces have no real correlation in XML schema. There's no way to represent the data. Base classes will work however.

HTH,
Drew
Nov 21 '05 #2
LS
Hello

"....interfaces have no real correlation in XML schema..."

In an interface you can declare public properties

If a class has public properties, the Serializer works ok. We were
expecting the same, using the interface....
Best regards
"Drew Marsh" wrote:
LS wrote:
Can a WebMethod return an Interface type?
Can we pass an interface parameter ?


The short answer is "no". You'll get an error just trying to generate any kind of service description along the lines of:

Cannot serialize interface TestWebService.IFoo.

If you think about it, interfaces have no real correlation in XML schema. There's no way to represent the data. Base classes will work however.

HTH,
Drew

Nov 21 '05 #3
LS wrote:

"....interfaces have no real correlation in XML schema..."

In an interface you can declare public properties

If a class has public properties, the Serializer works ok. We were
expecting the same, using the interface....


Sure, but you're serializing the class, not the interface, in that case. All the web method knows about here is the interface, it has no clue what concrete types you're going to hand it and there's no way to decorate your interface with XmlIncludeAttribute since it's only applicable to classes (not interfaces). This is not even a web service limitation, it's an XML serializer limitation. The web service is just trying to use the XmlSerializer and ends up getting this exception:

[NotSupportedException: Cannot serialize interface TestWebService.IFoo.]
System.Xml.Serialization.TypeScope.ImportTypeDesc( Type type, Boolean canBePrimitive, MemberInfo memberInfo)
System.Xml.Serialization.TypeScope.GetTypeDesc(Typ e type, MemberInfo source, Boolean directReference)
System.Xml.Serialization.TypeScope.GetTypeDesc(Typ e type)
System.Xml.Serialization.XmlReflectionImporter.Imp ortMemberMapping(XmlReflectionMember xmlReflectionMember, String ns, XmlReflectionMember[] xmlReflectionMembers)
System.Xml.Serialization.XmlReflectionImporter.Imp ortMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement)

Next, the XML serializer won't even look at attributes on interfaces. For example if you have something like:

public interface IFoo
{
[XmlAttribute("name")]
string Name { get; set; }
}

[XmlRoot("foo", Namespace="http://test.com/fooschema.xsd")]
[XmlType("FooA", Namespace="http://test.com/fooschema.xsd")]
public sealed class FooA : IFoo
{
private string name;

#region IFoo Members

public string Name
{
get
{
return this.name;
}

set
{
this.name = value;
}
}

#endregion
}

That class will serialize to:

<foo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://test.com/fooschema.xsd">
<Name>Test Foo!</Name>
</foo>

Notice the <Name> as opposed to what I decorated the IFoo as? If it obeyed IFoo's serialization attributes it would have looked like this (an attribute instead):

<foo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://test.com/fooschema.xsd" name="Test Foo!"/>

HTH,
Drew
Nov 21 '05 #4
LS
Hello

That's the conclusion. It's a limitation in the XML Serializer.

1. It compiles OK.
2. When starting the WebService application, it throws the exception.
Why we need to specify parameters and return objects as Interfaces ?

We have a complex and huge application, where some Assemblies are
replaceable dynamically . So we need to take full advantage of object
oriented features. That's why we need the Interfaces.

When accessing Assembly A thru A's Interface (defined in Assembly IA), from
Assembly B, this strategy works ok, as in any other OO language.

When exposing A thru a Web Service, we have the problem. The XML Serializer
is not capable of doing with an Interface, the very same it does with a
class. There is no reason for that. The only limitation is that microsoft
didn't see this, and didn't implement it.

The direct consequence, is one big problem.

Solution 1: Not take full advantage of OO features

Solution 2: Have a second definition of a property in the class implementation

public Interface IEntity
{
IPhones phones {get; set; }
}

in the class that implements the interface

public class Entity: IEntity
{
[XmlIgnore]
IPhones IEntity.phones {get ..... ; set ...... ; } // Interface for
other Assemblies

public Phones phones {get ...... ; set ...... ; } // For the
WebService,... not very nice...
}

What we hope: VisualStudio.NET 2005 ===> please, look into this...

Best regards

LS
"Drew Marsh" wrote:
LS wrote:

"....interfaces have no real correlation in XML schema..."

In an interface you can declare public properties

If a class has public properties, the Serializer works ok. We were
expecting the same, using the interface....


Sure, but you're serializing the class, not the interface, in that case. All the web method knows about here is the interface, it has no clue what concrete types you're going to hand it and there's no way to decorate your interface with XmlIncludeAttribute since it's only applicable to classes (not interfaces). This is not even a web service limitation, it's an XML serializer limitation. The web service is just trying to use the XmlSerializer and ends up getting this exception:

[NotSupportedException: Cannot serialize interface TestWebService.IFoo.]
System.Xml.Serialization.TypeScope.ImportTypeDesc( Type type, Boolean canBePrimitive, MemberInfo memberInfo)
System.Xml.Serialization.TypeScope.GetTypeDesc(Typ e type, MemberInfo source, Boolean directReference)
System.Xml.Serialization.TypeScope.GetTypeDesc(Typ e type)
System.Xml.Serialization.XmlReflectionImporter.Imp ortMemberMapping(XmlReflectionMember xmlReflectionMember, String ns, XmlReflectionMember[] xmlReflectionMembers)
System.Xml.Serialization.XmlReflectionImporter.Imp ortMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement)

Next, the XML serializer won't even look at attributes on interfaces. For example if you have something like:

public interface IFoo
{
[XmlAttribute("name")]
string Name { get; set; }
}

[XmlRoot("foo", Namespace="http://test.com/fooschema.xsd")]
[XmlType("FooA", Namespace="http://test.com/fooschema.xsd")]
public sealed class FooA : IFoo
{
private string name;

#region IFoo Members

public string Name
{
get
{
return this.name;
}

set
{
this.name = value;
}
}

#endregion
}

That class will serialize to:

<foo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://test.com/fooschema.xsd">
<Name>Test Foo!</Name>
</foo>

Notice the <Name> as opposed to what I decorated the IFoo as? If it obeyed IFoo's serialization attributes it would have looked like this (an attribute instead):

<foo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://test.com/fooschema.xsd" name="Test Foo!"/>

HTH,
Drew

Nov 21 '05 #5
You can get pretty close to this using schema inheritence (which maps to
class inheritence) instead of using interfaces. The short of it is that
the web service standards do not support interfaces, so the extension of
this is that the CLR web service tooling and infrastructure also has no way
to support your requirement at the moment.

I hope this helps

Dan Rogers
Microsoft Corporation
--------------------
Thread-Topic: webmethod returning interface or receiving an interface param
thread-index: AcTONicxHSMzv+4sQzeeqjry2/u8UA==
X-WBNR-Posting-Host: 81.193.248.227
From: "=?Utf-8?B?TFM=?=" <LS@discussions.microsoft.com>
References: <DF**********************************@microsoft.co m>
<#n**************@TK2MSFTNGP10.phx.gbl>
<83**********************************@microsoft.co m>
<#Y**************@TK2MSFTNGP10.phx.gbl>
Subject: Re: webmethod returning interface or receiving an interface param
Date: Fri, 19 Nov 2004 04:49:05 -0800
Lines: 122
Message-ID: <77**********************************@microsoft.co m>
MIME-Version: 1.0
Content-Type: text/plain;
charset="Utf-8"
Content-Transfer-Encoding: 7bit
X-Newsreader: Microsoft CDO for Windows 2000
Content-Class: urn:content-classes:message
Importance: normal
Priority: normal
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
Newsgroups: microsoft.public.dotnet.framework.webservices
NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.1.29
Path:
cpmsftngxa10.phx.gbl!TK2MSFTNGXA06.phx.gbl!cpmsftn gxa06.phx.gbl!TK2MSFTNGP08
phx.gbl!TK2MSFTNGXA03.phx.gbl
Xref: cpmsftngxa10.phx.gbl
microsoft.public.dotnet.framework.webservices:7556
X-Tomcat-NG: microsoft.public.dotnet.framework.webservices

Hello

That's the conclusion. It's a limitation in the XML Serializer.

1. It compiles OK.
2. When starting the WebService application, it throws the exception.
Why we need to specify parameters and return objects as Interfaces ?

We have a complex and huge application, where some Assemblies are
replaceable dynamically . So we need to take full advantage of object
oriented features. That's why we need the Interfaces.

When accessing Assembly A thru A's Interface (defined in Assembly IA), from
Assembly B, this strategy works ok, as in any other OO language.

When exposing A thru a Web Service, we have the problem. The XML Serializer
is not capable of doing with an Interface, the very same it does with a
class. There is no reason for that. The only limitation is that microsoft
didn't see this, and didn't implement it.

The direct consequence, is one big problem.

Solution 1: Not take full advantage of OO features

Solution 2: Have a second definition of a property in the class
implementation

public Interface IEntity
{
IPhones phones {get; set; }
}

in the class that implements the interface

public class Entity: IEntity
{
[XmlIgnore]
IPhones IEntity.phones {get ..... ; set ...... ; } // Interface for
other Assemblies

public Phones phones {get ...... ; set ...... ; } // For the
WebService,... not very nice...
}

What we hope: VisualStudio.NET 2005 ===> please, look into this...

Best regards

LS
"Drew Marsh" wrote:
LS wrote:

"....interfaces have no real correlation in XML schema..."

In an interface you can declare public properties

If a class has public properties, the Serializer works ok. We were
expecting the same, using the interface....
Sure, but you're serializing the class, not the interface, in that case.

All the web method knows about here is the interface, it has no clue what
concrete types you're going to hand it and there's no way to decorate your
interface with XmlIncludeAttribute since it's only applicable to classes
(not interfaces). This is not even a web service limitation, it's an XML
serializer limitation. The web service is just trying to use the
XmlSerializer and ends up getting this exception:
[NotSupportedException: Cannot serialize interface TestWebService.IFoo.]
System.Xml.Serialization.TypeScope.ImportTypeDesc( Type type, Boolean canBePrimitive, MemberInfo memberInfo) System.Xml.Serialization.TypeScope.GetTypeDesc(Typ e type, MemberInfo source, Boolean directReference) System.Xml.Serialization.TypeScope.GetTypeDesc(Typ e type)
System.Xml.Serialization.XmlReflectionImporter.Imp ortMemberMapping(XmlReflec
tionMember xmlReflectionMember, String ns, XmlReflectionMember[]
xmlReflectionMembers) System.Xml.Serialization.XmlReflectionImporter.Imp ortMembersMapping(XmlRefle
ctionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement)
Next, the XML serializer won't even look at attributes on interfaces. For example if you have something like:
public interface IFoo
{
[XmlAttribute("name")]
string Name { get; set; }
}

[XmlRoot("foo", Namespace="http://test.com/fooschema.xsd")]
[XmlType("FooA", Namespace="http://test.com/fooschema.xsd")]
public sealed class FooA : IFoo
{
private string name;

#region IFoo Members

public string Name
{
get
{
return this.name;
}

set
{
this.name = value;
}
}

#endregion
}

That class will serialize to:

<foo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://test.com/fooschema.xsd"> <Name>Test Foo!</Name>
</foo>

Notice the <Name> as opposed to what I decorated the IFoo as? If it obeyed IFoo's serialization attributes it would have looked like this (an
attribute instead):
<foo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://test.com/fooschema.xsd" name="Test Foo!"/>
HTH,
Drew


Nov 21 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by sd | last post: by
2 posts views Thread by Alin Popovici | last post: by
reply views Thread by George Durzi | last post: by
5 posts views Thread by John | last post: by
3 posts views Thread by Khurram | last post: by
1 post views Thread by gcdp | last post: by
reply views Thread by gcreed | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.