views:

1592

answers:

3

Im trying to create a web services that takes some arguments in its constructor to save round trips, but i keep getting the error: CS1729 "servicename" does not contain a constructor that takes '1' arguments

although when I try to create an instant locally (in the same project as the service) everything works fine... what gives?

web service:

public class ayyash : System.Web.Services.WebService {

    private string _myname;
    public ayyash (string myname) {


     _myname = myname;

        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }
}

consumption:

ayyash a = new ayyash("my name is ayyash");

output:

Compiler Error Message: CS1729: 'ayyash' does not contain a constructor that takes '1' arguments
+1  A: 

The default constructor will be called when the service host creates an instance in request to a service request message.

Why not get the default constructor to get the data it needs? You could delegate to the parameterised constructor.

public MyWebService : this(xxx) {}

What I mean is that the service host will always create an instance of your class (to handle the request via the default constructor. If you want to pass parameters to it you have a number of options:

  1. In the Default constructor go off the locate the data it needs
  2. Pass the data in the Request
  3. Possibly (I'm not sure) extend/modify the asp.net request response pipe line to use a different service instance creation mechanism. This link has some further examples.

I believe that WCF will allow you to do this easily more easily. Also you can use the HTTPListener directly.

Preet Sangha
how? how do I pass arguments to the default constructor?
Ayyash
If you don't need the default constructor, modify it to take the argumnents you need. Otherwise copy it and add the arguments. This code first approach is not considered to be the best approach to web service development. It may be better but slower to generate WSDL and schemas yourself and work from that.
BrianLy
i dont think you understand, or may be I am missing something, default contructors (by default) do not accept arguments, and no matter what I try, the client does not invoke any contructor with argument list... is that documented anywhere about c# .net web services?
Ayyash
@Ayyash. This is exactly what I'm saying. The service host out of the box always uses the default constructor. If you want the constructor to have data get the DEFAULT constructor call out and get it from somewhere else.
Preet Sangha
+1  A: 

When the client is "instantiating" your web service it is not calling the constructor on your service. It is instantiating a local proxy object that represents your service. The proxy object generated by .NET only supports a default constructor. This is why you get a compiler error.

The reason why the local object works is that you are not actually calling a web service. You are simply instantiating a local object and then calling a method on it.

I think you need to change your approach to pass in all of the data required to the WebMethod. The typical approach with web services is to have a stateless service that accepts all of the data required to perform the requested operation.

For example:

[WebMethod]
public string DoSomething(string name, string otherData)
{
    ayyash yourObject = new ayyash(name);

    return yourObject.DoIt(otherData);
}
Tuzo
actually my default constructor does get called (i am using visual studio) but i cannot overload it, thats the issue im facing, but i like your thinking, i do need to get used to this "stateless" concept...
Ayyash
The constructor gets called on the service side to process the request. He wants the non default constructor to be called.
Preet Sangha
i read in this article [http://www.xml.com/pub/a/ws/2003/01/08/randyray.html] the following:"It is important to note here that overloaded operations are supported in WSDL 1.1 (see the links in the "Resources" section below),but have been removed from the draft specification for WSDL 1.2. "
Ayyash
+2  A: 

The server side constructor is not called when you instantiate your client proxy. It is called when the server side object is created; that is, if and when a web service method is called.

Also worth nothing is that you cannot have instance members on a web service. You cannot accept "name" in the constructior and use it from other methods; you must send in "name" into each web service method as an argument. In short, web service "state" must be passed to the service via method arguments or a cookie (though using the latter will cause you problems if you move to WCF).

Just imagine that everytime you call a method on your proxy object, a new server side object is created and that method is called before the object is destroyed. This is not strictly true (the object can be pooled), but it will help you design your web services.

Richard Szalay
yes it does help, do you know of any documentation or articles to explain the state of webservices? im looking for an answer to: why do private variables preserve values if set inside the constructor, but not if set in a webmethod?
Ayyash
That scenario does sound strange, but it's most likely because you are receiving a pool instance vs a new instance purely by chance. Your only member variables in a web services (ASMX or WCF) should be dependencies (ie. repositories and such). Trying to store state in web service member variables will only cause you pain.
Richard Szalay