可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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:
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.
回答2:
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); }
回答3:
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:
- In the Default constructor go off the locate the data it needs
- Pass the data in the Request
- 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.