I try to implement simple SOAP server on ASP.NET and simple client on php and get the problem with response and request format.
My server is very simple, take one string and return another:
[WebMethod]
public string HelloWorld(string Additional) {
return "Hello " + Additional;
}
I expect, that php client is such simple:
$client = new SoapClient('path');
print_r($client->HelloWorld('homm'));
Hello homm
But actually, function take only objects and return object with single member — HelloWorldResult:
$client = new SoapClient('path');
print_r($client->HelloWorld(array('Additional' => 'homm')));
stdClass Object
(
[HelloWorldResult] => Hello homm
)
Can I change this behavior? What part I need to change, server (ASP.NET) or client(php) to work with results and parameters indirect?
Related
I have .NET Web API Project for the fulfillment API as our webhook in my Dialogflow agent. In our Post method of the controller, after getting the request from Dialogflow, I implement the explicit authentication as shown in the Google Cloud documentation for C#.
//jsonFileName is the name of the serviceAccountKey json generated from the Google Cloud Platform that's encrypted internally
public bool AuthExplicit(string projectId, string jsonFileName)
{
try
{
string JsonCredential = DecryptHelper.Decrypt(jsonFileName);
var credential = GoogleCredential.FromJson(JsonCredential).CreateScoped(LanguageServiceClient.DefaultScopes);
var channel = new Grpc.Core.Channel(
LanguageServiceClient.DefaultEndpoint.ToString(),
credential.ToChannelCredentials());
var client = LanguageServiceClient.Create(channel);
AnalyzeSentiment(client);
if (client != null)
{
return true;
}
else
{
return false;
}
}
internal void AnalyzeSentiment(LanguageServiceClient client)
{
var response = client.AnalyzeSentiment(new Document()
{
Content = "Authenticated.",
Type = Document.Types.Type.PlainText
});
var sentiment = response.DocumentSentiment;
string score = $"Score: {sentiment.Score}";
string magnitude = $"Magnitude: {sentiment.Magnitude}";
}
The difference with the code is that after getting the client, when we call the AnalyzeSentiment() method, it doesn't do anything, and the projectId parameter is never used to authenticate. GCP docs are quite confusing, since when there is an AuthExplicit() that uses projectId, it uses it as a parameter for the buckets and only prints this on the console.
It works fine, until we test the service account key with a different agent. Expected output is that authentication would fail, but somehow it still passes.
Once the Post method goes through the AuthExplicit() method, it would only return a boolean. Is this the right way to authenticate? Or is there something else needed to invoke?
The difference with the code is that after getting the client, when we call the AnalyzeSentiment() method, it doesn't do anything,
Does client.AnalyzeSentiment() return an empty response? Does the call hang forever?
It works fine, until we test the service account key with a different agent.
What is a different agent? A different User-Agent header?
Once the Post method goes through the AuthExplicit() method, it would only return a boolean. Is this the right way to authenticate? Or is there something else needed to invoke?
What does 'the Post method' refer to? What is the 'it' that would only return a boolean?
I have a service that contains a lot of functions with out parameters to return a few extra parameters.
I was wondering if it's possible to call a regular asp.NET web api service with out parameters and receive a value(in the form of out parameters, separate from the return value) from the service.
If it is possible, could you elaborate on what I need to do to achieve this?
Any help will be well appreciated.
No, this is not possible. The response from WebAPI will be a normal HTTP response with a body where the serialized returned data will be.
Of course, as usual, your response can be a complex object to serialize and you can include those out returns as members of it. For example:
public IHttpActionResult GetResponse(int id)
{
int outputInt;
string outputString;
YourMethodWithOutParameters(id, out outputInt, out outputString);
return Ok(new
{
Id = id,
OutputInt = outputInt,
OutputString = outputString,
});
}
server
public void SendToUser(string serverId, string message)
{
//Console.WriteLine(string.Format("New Msg. Send to {0}, Msg content:{1}", serverId, message));
var _identity = ConnectedUsers.FirstOrDefault(aa => aa.serverId == serverId);
var aaa = Clients.Client(_identity.connectionId).RcvSendToUser(message);
}
Client
_hub.On("RcvSendToUser", x => Console.WriteLine(x) );
My question is:
Server side and Client side are both Console project.
Can I return value on _hub.on("RcvSendToUser") ? And if yes, how can I get this value at server side?
it is not possible to get return values from methods called at the client. One can argument, that a strong-typed hub can be used where the used interface defines some methods that return values.
link
I am trying to use WDSL SOAP in PHP. The initial connection seems to work fine but I am struggling to 'convert' some C# to PHP, in particular headers.
AreaSearchRequest request = new AreaSearchRequest();
request.GUID = "1234";
request.Location = "UK";
// Create AreaSearchHeader, assign AreaSearchRequest
AreaSearchHeader header = new AreaSearchHeader();
header.Request = request;
header.Validate = false;
// SOAP connection
soap.Open();
// Call the AreaSearch method response object
AreaSearchResponse response = soap.AreaSearch(header);
//Close API connection
soap.Close();
And here is my rough translation into PHP.
$wsdl = "https://whatever/";
$options = array(
'trace' => 1,
);
$client = new SoapClient($wsdl, $options);
$request = array(
'GUID' => '1234',
'Location' => 'UK',
);
$client->__soapCall('AreaSearch', $request);
What is really throwing me off is the header stuff to make a valid request! Thanks (sorry, I have no experience of C# whatsoever).
try using nusoap https://sourceforge.net/projects/nusoap/ to do the heavy lifting. I dont use PHP myself but a have a load of c# soap services that people I work with use nusoap to consume and they haven't had any issues
I'm working with a rather large query string(~30+ parameters) and am trying to pass them to a WCF service I've setup.
I've run into a few issues specifically with the UriTemplate field. This service is setup to access a third party Api, so the query string may or may not contain all parameters. I'm curious if the best approach is to build a query string and pass that to the WCF service or to pass each parameter(and in some cases String.Empty) individually.
I've currently tried to dynamically build up a query string, however have hit a wall with either a 403 error when I try to pass the entire string( "?prm1=val&prm2=val" ) into the uritemplate of "ApiTool.jsp{query}", or I hit an invalid uritemplate response due to the fact I don't have name/value pairs listed.
I am pretty sure you'll need to list the parameters individually. Otherwise, UriTemplate will end up escaping things for you:
var ut = new UriTemplate("Api.jsp{query}");
var u = ut.BindByName(new Uri("http://localhost"), new Dictionary<string, string>() { { "query", "?param1=a¶m2=b" } });
Console.WriteLine(u); // http://localhost/Api.jsp%3Fparam1=a¶m2=b
You can 'unescape' querystring with IClientMessageInspector.
public class UriInspector: IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
// change/replace request.Headers.To Uri object;
return null;
}
}
See MSDN how to add this to your Endpoint object.