Webservice C# constructor does not allow arguments? - c#

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

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.

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);
}

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.

Related

c# SOAP with service reference is not showing real response

I'm creating an UWP app, that needs to connect to asmx service. I've done that by using service reference, which works with TempConvert but not with my asmx service
This is how my code looks like
HelpdeskSoapClient HPsoapClient = new HelpdeskSoapClient();
getIncInput input = new getIncInput();
input.username = "450";
getIncResponse realresponse;
realresponse= await HPsoapClient.getIncAsync(input);
Debug.Write(realresponse);
but response is not an XML file or something else, but "DTS.helpdesk.getIncResponse"
Any clues ?
getIncResponse is the object that is returned by the service when you make the call.
When you pass realResponse into the Debug.Write, since it's an object, the base functionality of ToString() is called, which unless overridden in the object will return the fully qualified type name - i.e., DTS.helpdesk.getIncResponse.
You should be able to access the properties of the object to get the data, similar to how you set the username on the getIncInput object (input.username = "450";).
The temperature conversion service worked because it returns a simple type (string), not a complex type (getIncResponse). There is no error here.

How to access a web service with the following parameters and client proxy generated based on a wsdl

I have been provided with a WSDL and have generated the proxy class based on this WSDL. Sorry cannot provide the WSDL due to security concerns. The method in the proxy class that I'd like to call is:
public HeaderValueType GetStatus(System.DateTime RequestorTrxTime, string RequestorContext, string MessageIdentifier, string ProfileNumber, string ProfileType, int RequestIndicator, out ResponseBodyType Response) {//Some code}
I am just wondering what the fields
string RequestorContext, string MessageIdentifier
Are meant to be because I have seen requestorContext being passed as an object like this:
OperationContext.Current.InstanceContext
But not as a string the same goes for MessageIdentifier.
I have not got access to the creators of this WSDL for a while and cant get access, so I thought if any one would have a clue.
Did you try calling the service just be passing some values into these fields? It looks more like naming coincidence. Check that linked XSDs from WSDL specify this as message content. Also check that WSDL contains policy assertion called CompositeDuplex and assertions for reliable messaging (it should be called RMAssertion). It it doesn't it is not WsDualHttpBinding where InstanceContext is used to expose callback contract and those parameters are only data related - meaning of those parameters must be described by service provider.

.NET WebService WebMethod with custom object as Parameter

I have created a .NET WebService. There I have implemented the following WebMethod:
[WebMethod]
public string CheckLicense(License license) {
return "";
}
The Type License comes from a different Assembly X which I have referenced to the WebService. The Fulltype of License is Prayon.Shared.Library.Licensing.License
Now, I have build a client which also references the Assembly X. When I try no to call the WebService with CheckLincense:
private void CheckLicense(License license) {
using(var service = new Prayon.Service.Web.PrayonService()) {
service.CheckLicense(license);
}
}
There service.CheckLicense() want an object of Type Prayon.Service.Prayon.Service.Web.License.
I don't know what I am doing wrong. What does I have to do, that I can pass a object of Type Prayon.Shared.Library.Licensing.License to service.CheckLicense()?
If you want to use a method in your License object you need to :
Call your WebService, obtain a service.License object, use it to create an instance of your local License object, after that you will have your 'local' License object with state (properties) filled by your WebService answer.
Otherwise i do not see why you would want to use a 'local' License object ?
You should not share the assembly between your web service and your client but instead create an instance of your License from your web service proxy types (should be found into service.x)
You need to create an instance from the webserviceproxy rather than from the asembly.
When you add a service reference to your webserice from the client it will generate proxy classes for you.Inside these you will have the License defined.use this to create an instance and pass it rather than referencing directly from your assembly.

Invoking WCF functions using Reflection

I have a WCF application that is using NetTcpBinding. I want to invoke the functions in WCF service using Methodbase.Invoke from the System.Reflection namespace. In other words I want to Dynamically call a Function by passing a String as the Function name.
Reflection works great for Web Service or a Windows application or any DLL or class. So there is certainly a way to do this for WCF but I am unable to find out how.
I am getting the Assembly Name then it's type everything fine but as we cannot create an instance of the Interface class. I tried to open the WCF connection using the binding and tried to pass that object but it's throwing an exception as:
"Object does not match target type."
I have opened the connection and passed the object and type is of interface only. I don't know whether I'm trying the wrong thing or am using the wrong way. Any idea how I can accomplish this?
The NetTCPBinding all are properly given while opening the connection. I am using WCF as a Windows Service using NETTCPBinding.
You are passing the correct instance when you invoke your method. This instance is the proxy object created via the interface-based call to ChannelFactory. I tried your technique on a hello world style application and got the expected results. One thing I don't see in your code example is how you initialize the parameters. That could be a problem. I believe think that your call to Type.GetType may be causing the error you are receiving. Notice I call GetType on the Proxy object. I include my sample code below that calls a Function GetData that takes one argument as an integer.
...
Dim myFactory As ChannelFactory(Of SimpleService.IService1)
myFactory = New ChannelFactory(Of SimpleService.IService1)(myBinding, myEndpoint)
oProxy = myFactory.CreateChannel()
'commented out version that does same call without reflection
' oProxy.GetData(3)
Dim oType As Type = oProxy.GetType
Dim oMeth As MethodInfo = oType.GetMethod("GetData")
Dim params() As Object = {3}
Dim sResults As String
sResults = oMeth.Invoke(oProxy, BindingFlags.Public Or BindingFlags.InvokeMethod, Nothing, params, System.Globalization.CultureInfo.CurrentCulture)

How to add SoapExtension attribute to generated web service client proxy without modifying the generated class?

I have created a SoapExtension class to capture the soap request and response from specific web service calls. In order to put this SoapExtension into effect, I have to add an attribute to the method in the generated proxy client.
For example, I've added the AuditSoapCapture attribute to this method:
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://blahblah.com/webservices/AddressSearch", RequestNamespace = "http://blahblah.com/webservices/", ResponseNamespace = "http://blahblah.com/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[blahblah.TriadLite.Core.AuditSoapCapture]
public System.Data.DataSet AddressSearch(string HouseNumber, string StreetName, string ZipCode) {
object[] results = this.Invoke("AddressSearch", new object[] {
HouseNumber,
StreetName,
ZipCode});
return ((System.Data.DataSet)(results[0]));
}
I am looking for a way to add this attribute to specific methods without modifying the generated client proxy, as they will get lost when we regenerate. Can I do this in a another partial class or interface or some other way?
Thanks!
Unfortunately, you'll need to modify the proxy code. The other possibilities you mention will not work - a parial class will not overwrite existing functionality, and there is no way that I'm aware of getting an interface to do what you need (compounded by the fact that there is no way to even let the proxy generator know that you intend to implement an interface).
Something that I've done in the past, in a situation where you have access to the source of the webservice, is to write a little app that will parse the code (as text) in the .asmx.cs file of the webservice to extract the names of all the methods that are tagged with [WebMethod]. Then the app "fixes up" the References.cs by inserting appropriate attributes onto the proxied methods, based on some settings file or somesuch. This works well because the naming conventions in the proxy map very neatly to the method names in the original service.
I may just end up injecting my SoapExtension by putting it into the Web.config. This will cause it to be run on every WS call without a client proxy method attribute. Then, I will modify the SoapExtension to look up the called WS method name on a list, and if it is on the list, then do the rest of the SoapExtension logic. I figure the hit on the list in this small volume application isn't going to kill performance.
6 years ago this was posted... So not sure if this will help anyone at this point.
I ran into something similar with a call to an old SOAP web service that had a dynamically generated proxy class that we didn't want to modify as it was auto-generated from the wsdl by the project. In order to solve this problem here is what we did.
The proxy class generated by wsdl.exe is a partial class. We extended this class like so to add a property with the information we wanted to access in the soapextension. You can add as many properties as you want...
partial class mysoapwebservice
{
public string myproperty{ get; set; }
}
in the web.config we registered the soap extension globaly on the project
<webServices>
<soapExtensionTypes>
<add type="MySoapExtension" priority="1" group="Low"/>
</soapExtensionTypes>
</webServices>
In the code were we created the web service object 'mysoapwebservice' we set the value of the property we needed.
In the soapextension you can get a reference to the web service that was called as well as the values. You can also determine the method call.
`
public class MySoapExtension: SoapExtension
{
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
{
// web service client object
var webserviceobject= ((SoapClientMessage)message).Client;
// method from web service that was called
var calledMethod = (SoapClientMessage)message).MethodInfo;
// checked the client type of webserviceobject and
//added method / property specific logic here
}
}
}
// other soap extension code
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class CriptoExtensionAttribute : SoapExtensionAttribute
[CriptoExtension]
public partial class MainService{

Categories

Resources