c# SOAP with service reference is not showing real response - c#

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.

Related

How to consume WCF after passing C# class object

My WCF contains two methods. The first is simple which returns string and takes string as parameter, but in second method I am passing a class containing properties as parameter and return string.
When I comment second method then I am able to get WCF_Masters.ServiceClient object in client application but after uncommenting 2nd method I am unable to get that object.
I get only CompositeType instead of ServiceClient of My WCF service whose name is WCF_Masters.
Note that I am trying to consume WCF in WPF Windows application.
How can I get rid of this issue?
Edit
My WCF methods are:
public String GetMessage(string vName)
{
return "Hello world from " + vName;
}
public String SaveEmployee(EmployeeMasterSC vEmployeeMasterSC)
{
String mReturnMsg = string.Empty;
EmployeeMasterDAL vEmployeeMasterDAL = null;
vEmployeeMasterDAL = new EmployeeMasterDAL();
mReturnMsg = vEmployeeMasterDAL.SaveEmployee(vEmployeeMasterSC);
//mEmpDset.EmployeeData = Mdset; return mReturnMsg;
}
If I understood you correctly, you should not be adding a reference to your WPF DLL in your WCF service. Define the model in your service and then instantiate that model (by reference) in your WPF application, which is consuming the service.
I believe the reason it works when you comment out the 2nd method is that your 1st method has no reference to class structures defined in the WPF DLL.
Got the solution guys, It was the issue of database name I have Written incorrectly "AirportPortal" instead of "DB_AirportPortal" in WCF while inserting records into database

WCF Rest service retunrs different type(string or image) based on input parameters

I already have a WCF Rest service that returns image(as stream).
/rest/getimage
and this is my contract is
Stream GetImage();
and it works fine.
now I want to change this service to accept parameter, based on the parameter, I return image(stream)
or image url(string). something like that:
/rest/getimage?format=url|image
I changed return type of GetIamge to dynamic and added [ServiceKnownType(typeof(Stream))]
but when I call the url in browser ,instead getting image, I got this:
<FileStream xmlns="http://schemas.datacontract.org/2004/07/System.IO" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><__identity i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System"/></FileStream>
the code is the same as working code, I noticed if I changed returning type from Stream to dynamic or object, I got this error.
I cannot add another endpoint(we should have only one endpoint).

How do I return a dynamically typed object in my C# web service?

I have a followup question to this question.
I'm writing a web service which dynamically calls other web services, using the WSProxy class found here.
Using WSProxy returns an object with a dynamic type, depending on the web service method called. For example, if I'm calling a method that returns...
<StateCodes>
<StateCode>
<Code>AL</Code>
<Name>Alabama</Name>
</StateCode>
<!-- and so on -->
</StateCodes>
then the object is of the type StateCodes[].
If I'm calling a method that returns ...
<GetVehicleMakes>
<VehicleMakes>
<Vehicle_Make_Code>00</Vehicle_Make_Code>
<Vehicle_Make_Description>Ford</Vehicle_Make_Description>
</VehicleMakes>
<VehicleMakes>
<Vehicle_Make_Code>01</Vehicle_Make_Code>
<Vehicle_Make_Description>Toyota</Vehicle_Make_Description>
</VehicleMakes>
<!-- and so on -->
</GetVehicleMakes>
then the object is of the type GetVehicleMakes[].
I can't declare a class type beforehand because the class type of the returned object is determined by the web service method called, and the web service method is determined at runtime. There are dozens of methods with different return types on the local service I'm testing against. I don't get to know the type of the returned object before runtime, because any method from any web service could be called.
When I try to return the object straight up, like so:
[WebMethod]
public object RunService(string webServiceAsmxUrl, string serviceName, string methodName, string jsonArgs)
{
WSDLRuntime.WsProxy wsp = new WSDLRuntime.WsProxy();
// Convert JSON to C# object.
JavaScriptSerializer jser = new JavaScriptSerializer();
var dict = jser.Deserialize<Dictionary<string,object>>(jsonArgs);
object result = wsp.CallWebService(webServiceAsmxUrl, serviceName, methodName, dict);
// This line produces the error.
return result;
}
I can insert a breakpoint at the return result line, and browse my result object. For example, when I call the StateCodes method, the result variable is the StateCodes[] array.
However, once return result runs, the XML parser won't have it.
System.InvalidOperationException: The type StateCodes[] may not be used in this context.
I've searched for answers, and I see terms like, "reflection" and "serialization" coming up, but I am very new to C# and don't know if these are what I want or how they work.
I'm using C# 3.5.
It looks like you need to return the xml that is returned from the service call. You can't return the object directly because the top-level service (the one that has a return type of object) is not generated at runtime; it is defined when its wsdl is consumed.
Long story short, you should change the return type of your top-level WebMethod to be string and serialize result manually in order to do what you want. Then the client (who presumably knows what they expect to get back from the service that they are requesting via webServiceAsmxUrl, serviceName, and methodName) can deserialize the result themselves.

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)

Webservice C# constructor does not allow arguments?

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.

Categories

Resources