By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,315 Members | 1,736 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,315 IT Pros & Developers. It's quick & easy.

Web Service interface versioning...

P: n/a
Hi,

Am new to web services, so apologies for the basic nature of the question -
and apologies in advance if this is the wrong newsgroup. We're building a
new web service and I'm looking around for documentation on a number of
issues, including versioning of web service interfaces...

I've spent the last few hours looking through books, Google, MSDN and
surprisingly I have found little or nothing that explains/shows how to
practically handle the evolution of a web service's interface over time. One
would have thought that this would be one topic where there would be an
abundance of information.

Our requirements for versioning a web service interface are:

(a) To ensure that a previously published interface never changes, so that
older clients still work: this can be further classified to include (i)
changes to method signatures, and (ii) changes to custom types passed in/out
to these methods

(b) To ensure that new interfaces are a superset of any existing old
interfaces, with the additional requirement that no code is repeated, so the
methods in the new interfaces that are the same as the old interface, simply
delegate calls to existing methods rather than repeating code.

(c) To keep the URL to the WSDL the same for all versions - in my opinion, a
WSDL is a description of a web service, and not the description of a version
of a webservice - I have seen many implementations of web service versioning
that simply use a different WSDL for each version - although it somewhat
works, I'm not sure that this is the ideal solution.

(d) To make all the changes in C# code (using attribute decoration), without
having to resort to directly modifying WSDL's or XSD files, especially after
auto-generation - in other words, we want to be able to use the built-in
web-service-related attributes within Visual Studio.NET to decorate our code
and not poke around modifying system-generated files...

The little that I've found, I list below along with why the
solution/explanation is not ideal (based on my understanding) for our
particular needs - both of them were written (wholly or partly) by Scott
Seely sometime in 2002:

(1)
http://msdn.microsoft.com/library/de...ce10152002.asp
This is a good article however with regards to adding new code it opts for
either having two ASMX files or manually editing the WSDL both of which are
not very attractive. For changing method signatures, it opts again for
having two separate ASMX files which again is not attractive.

(2)
http://msdn.microsoft.com/library/de...ce04032002.asp
Again another good article, however no references are made to the use of
attributes within C# code - the main thrust of this article is that
versioning should be done via the TargetNamespace
([WebService(Namespace="http://www.somecompany.com/Version1")]), which from
within VS.NET can be set as an attribute of the just above the Service class
(which inherits from System.Web.Services.WebService). From reading this, I
got the idea to put a new version of the web service into a second class
(within the same overall C# class (not XML!) namespace) also inheriting from
System.Web.Services.WebService, but this time decorate that class with a
different TargetNameSpace, for example
[WebService(Namespace="http://www.somecompany.com/Version2")] - this way, I
could have two separate classes representing each web service versions, with
each class being decorated by a versioned TargetNamespace, whilst still
sharing the same ASMX/URL.

The sample code I came up with is below (business logic has been replaced
with Apples and Pears and Oranges for IP reasons, however the mechanics are
the same). What I found is that when I run the service, only the methods
from the first class that is declared show up as being methods on the service
- the second class with the separate target namespace appears to be
completely ignored.

When I request a WSDL from the service, this also appears to reflect the
fact that the second class is completely ignored - what am I doing wrong?
Have I adopted the wrong approach? Is what I'm looking for (the 4 points (a)
to (d) above) impossible to achieve? Is there something very basic that I'm
missing?

Frankly, I find it hard to believe that there are no more than the two
complete articles listed above available on the net for web service
versioning using .NET, however I can't find any more! Any pointers to
documentation, in-code attributes, suggestions to fix my approach above or
even sample code etc for me to read up on would be extremely welcome...

Kind regards
Patrick

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Code pasted below:

using System;
using System.Web;
using System.Web.Services;
using System.ComponentModel;
using System.Web.Services.Protocols;

namespace SomeWebService
{
[Serializable()]
public class Apple
{
public string name;
public int age;

public Apple()
{
name = @"";
}
}

[Serializable()]
public class Pear
{
public string name;
public int age;
public Pear()
{
name = @"";
}
}

[Serializable()]
public class Orange
{
public string name;
public int age;
public Orange()
{
name = @"";
}
}

/// <summary>
/// Summary description for Service.
/// </summary>
[WebService(Namespace="http://www.somecompany.com/V1")]
public class Service1 : System.Web.Services.WebService
{
public Service1()
{
InitializeComponent();
}

#region Component Designer generated code
//Required by the Web Services Designer
private IContainer components = null;

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion

[WebMethod]
public Apple[] GetAppleList()
{
Apple[] apples = new Apple[ 3 ];
Apple a = new Apple();
a.name = @"Granny Smith";
a.age = 3;
apples[0] = a;

a = new Apple();
a.name = @"Golden Shine";
a.age = 4;
apples[1] = a;

a = new Apple();
a.name = @"Crunchy Green";
a.age = 5;
apples[2] = a;

return apples;
}

[WebMethod]
public Pear[] GetPearList()
{
Pear[] pears = new Pear[ 2 ];
Pear p = new Pear();
p.name = @"Avocado";
p.age = 9;
pears[0] = p;

p = new Pear();
p.name = @"Fruity Pear";
p.age = 10;
pears[1] = p;

return pears;
}
}

/// <summary>
/// Summary description for Service.
/// </summary>
[WebService(Namespace="http://www.somecompany.com/V2")]
public class Service2 : System.Web.Services.WebService
{
public Service2()
{
InitializeComponent();
}

#region Component Designer generated code
//Required by the Web Services Designer
private IContainer components = null;

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion

[WebMethod]
public Apple[] GetAppleList()
{
Service1 s = new Service1();
return s.GetAppleList();
}

[WebMethod]
public Pear[] GetPearList()
{
Service1 s = new Service1();
return s.GetPearList();
}

[WebMethod]
public Orange[] GetOrangeList()
{
Orange[] oranges = new Orange[ 2 ];
Orange o = new Orange();
o.name = @"Mandarin";
o.age = 9;
oranges[0] = o;

o = new Orange();
o.name = @"Tangarine";
o.age = 10;
oranges[1] = o;

return oranges;
}
}
}

Nov 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
hB
So What is the OPTIMAL solution found?
Or guys tell/guide us the alternatives/workarounds!

---
hB

Nov 22 '05 #2

P: n/a
Hello

I am not an expert on Semantic Webs and Ontologies but this is really some
thing that makes us think about the limitations of current WS Architecture.
For any approach (listed by you or otherwise) that we take to resolve such
issues would most probably be a workaround. Smeantic Web Services is one
initiative that is working to resolve such issuses. Following is an extract
from there mission statement.

The SWSI mission is threefold:
to create infrastructure that combines Semantic Web and Web Services
technologies to enable maximal automation and dynamism in all aspects of Web
service provision and use, including (but not limited to) discovery,
selection, composition, negotiation, invocation, monitoring and recovery; to
coordinate ongoing research initiatives in the Semantic Web Services area;
to promote the results of SWSI work to academia and industry.

I would also suggest you to take a look at following links:

http://www.swsi.org/
http://www.wsmo.org/TR/d2/v1.1/
http://www.wsmo.org/TR/d13/d13.4/v0.1


"PatrickSA" wrote:
Hi,

Am new to web services, so apologies for the basic nature of the question -
and apologies in advance if this is the wrong newsgroup. We're building a
new web service and I'm looking around for documentation on a number of
issues, including versioning of web service interfaces...

I've spent the last few hours looking through books, Google, MSDN and
surprisingly I have found little or nothing that explains/shows how to
practically handle the evolution of a web service's interface over time. One
would have thought that this would be one topic where there would be an
abundance of information.

Our requirements for versioning a web service interface are:

(a) To ensure that a previously published interface never changes, so that
older clients still work: this can be further classified to include (i)
changes to method signatures, and (ii) changes to custom types passed in/out
to these methods

(b) To ensure that new interfaces are a superset of any existing old
interfaces, with the additional requirement that no code is repeated, so the
methods in the new interfaces that are the same as the old interface, simply
delegate calls to existing methods rather than repeating code.

(c) To keep the URL to the WSDL the same for all versions - in my opinion, a
WSDL is a description of a web service, and not the description of a version
of a webservice - I have seen many implementations of web service versioning
that simply use a different WSDL for each version - although it somewhat
works, I'm not sure that this is the ideal solution.

(d) To make all the changes in C# code (using attribute decoration), without
having to resort to directly modifying WSDL's or XSD files, especially after
auto-generation - in other words, we want to be able to use the built-in
web-service-related attributes within Visual Studio.NET to decorate our code
and not poke around modifying system-generated files...

The little that I've found, I list below along with why the
solution/explanation is not ideal (based on my understanding) for our
particular needs - both of them were written (wholly or partly) by Scott
Seely sometime in 2002:

(1)
http://msdn.microsoft.com/library/de...ce10152002.asp
This is a good article however with regards to adding new code it opts for
either having two ASMX files or manually editing the WSDL both of which are
not very attractive. For changing method signatures, it opts again for
having two separate ASMX files which again is not attractive.

(2)
http://msdn.microsoft.com/library/de...ce04032002.asp
Again another good article, however no references are made to the use of
attributes within C# code - the main thrust of this article is that
versioning should be done via the TargetNamespace
([WebService(Namespace="http://www.somecompany.com/Version1")]), which from
within VS.NET can be set as an attribute of the just above the Service class
(which inherits from System.Web.Services.WebService). From reading this, I
got the idea to put a new version of the web service into a second class
(within the same overall C# class (not XML!) namespace) also inheriting from
System.Web.Services.WebService, but this time decorate that class with a
different TargetNameSpace, for example
[WebService(Namespace="http://www.somecompany.com/Version2")] - this way, I
could have two separate classes representing each web service versions, with
each class being decorated by a versioned TargetNamespace, whilst still
sharing the same ASMX/URL.

The sample code I came up with is below (business logic has been replaced
with Apples and Pears and Oranges for IP reasons, however the mechanics are
the same). What I found is that when I run the service, only the methods
from the first class that is declared show up as being methods on the service
- the second class with the separate target namespace appears to be
completely ignored.

When I request a WSDL from the service, this also appears to reflect the
fact that the second class is completely ignored - what am I doing wrong?
Have I adopted the wrong approach? Is what I'm looking for (the 4 points (a)
to (d) above) impossible to achieve? Is there something very basic that I'm
missing?

Frankly, I find it hard to believe that there are no more than the two
complete articles listed above available on the net for web service
versioning using .NET, however I can't find any more! Any pointers to
documentation, in-code attributes, suggestions to fix my approach above or
even sample code etc for me to read up on would be extremely welcome...

Kind regards
Patrick

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Code pasted below:

using System;
using System.Web;
using System.Web.Services;
using System.ComponentModel;
using System.Web.Services.Protocols;

namespace SomeWebService
{
[Serializable()]
public class Apple
{
public string name;
public int age;

public Apple()
{
name = @"";
}
}

[Serializable()]
public class Pear
{
public string name;
public int age;
public Pear()
{
name = @"";
}
}

[Serializable()]
public class Orange
{
public string name;
public int age;
public Orange()
{
name = @"";
}
}

/// <summary>
/// Summary description for Service.
/// </summary>
[WebService(Namespace="http://www.somecompany.com/V1")]
public class Service1 : System.Web.Services.WebService
{
public Service1()
{
InitializeComponent();
}

#region Component Designer generated code
//Required by the Web Services Designer
private IContainer components = null;

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion

[WebMethod]
public Apple[] GetAppleList()
{
Apple[] apples = new Apple[ 3 ];
Apple a = new Apple();
a.name = @"Granny Smith";
a.age = 3;
apples[0] = a;

a = new Apple();
a.name = @"Golden Shine";
a.age = 4;
apples[1] = a;

a = new Apple();
a.name = @"Crunchy Green";
a.age = 5;
apples[2] = a;

return apples;
}

[WebMethod]
public Pear[] GetPearList()
{
Pear[] pears = new Pear[ 2 ];
Pear p = new Pear();
p.name = @"Avocado";
p.age = 9;
pears[0] = p;

p = new Pear();
p.name = @"Fruity Pear";
p.age = 10;
pears[1] = p;

return pears;
}
}

/// <summary>
/// Summary description for Service.
/// </summary>
[WebService(Namespace="http://www.somecompany.com/V2")]
public class Service2 : System.Web.Services.WebService
{
public Service2()
{
InitializeComponent();
}

#region Component Designer generated code
//Required by the Web Services Designer
private IContainer components = null;

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion

[WebMethod]
public Apple[] GetAppleList()
{
Service1 s = new Service1();
return s.GetAppleList();
}

[WebMethod]
public Pear[] GetPearList()
{
Service1 s = new Service1();
return s.GetPearList();
}

[WebMethod]
public Orange[] GetOrangeList()
{
Orange[] oranges = new Orange[ 2 ];
Orange o = new Orange();
o.name = @"Mandarin";
o.age = 9;
oranges[0] = o;

o = new Orange();
o.name = @"Tangarine";
o.age = 10;
oranges[1] = o;

return oranges;
}
}
}

Nov 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.