Problems moving an web service to another server - asp.net

I have C#/ASP.NET web service which is running on a remote server and uses WSDL. It worked fine up until recently when it was moved to another server. However this means I had to change the database connection string, which was hard coded, so the code needed to be rebuilt on my development machine and uploaded to the server.
The service is called from a PHP script running on another web server using SOAP.
For some reason, from what I can tell, it's trying to run the old code, even though I've modified it.
e.g. if I change my web service function to just return, for example, "Hello, World", it seems to still try to connect to the database, etc. (but failing because that database no longer exists, I believe it's still trying to use the old connection string)
If I remove the function, it tells me that the function doesn't exist. (So it is looking in the right place)
If I add a new function and try to call it from the php script, I get the error
The server did not recognize the value of HTTP Header SOAPAction
If I try and test it on the actual server using the http://localhost/Myservice/Myservice.asmx everything works fine!
Here is the code I am using to call:
ini_set("soap.wsdl_cache_enabled", 0);
$client = new SoapClient("http://1.2.3.4:8083/MyService/MyService.asmx?WSDL&revision=1", array('cache_wsdl' => WSDL_CACHE_NONE));
$input = new stdClass;
$input->inputvals = '15707F';
echo "Functions: |";
print_r($client->__getFunctions()); // Lists all functions including new ones
echo "|\n\n";
$Response = $client->checkPrice($input);
print_r($Response);
To deploy the code this is what I'm doing - on local development machine, I Publish the solution to File System (for some reason I can't get IIS working on this machine). Then stop IIS on server machine, "Remove Application" in IIS, copy my files in, "Convert to Application", then restart IIS.

The server seems to get a wrong SOAPAction HTTP-Head attribute (which is part of the SOAP-standard) from your SOAP-Client. Check the wsdl for the expected one (wsdl:binding section) and make sure that you're sending it with the expected value.

OK, I'm not completely satisfied with this solution but here is how I got it working.
I don't know enough about WSDL to know why or how this happens, but the WSDL xml file had the following lines in it (as per my comment on my own original post).
<wsdl:service name="Myservice">
<wsdl:port name="MyserviceSoap" binding="tns:MyserviceSoap">
<soap:address location="http://1.2.3.4/Myservice/Myservice.asmx" />
</wsdl:port>
.
.
.
</wsdl:service>
Note the lack of the :8083 port on the location. Originally I had moved the service from 1.2.3.4 to 1.2.3.4:8083 in order to keep it running during the transition - the router then uses NAT to forward it to the correct server on their internal network. When the owners of the server had said they turned off, all they had turned off was the MS SQL server on that computer, so my old web service was still working away. (I had kind of taken their word for it when they said they had turned off the server)
To work around this, I overrode the __doRequest() function in the SoapClient class in my PHP client script to manually add the :8083 to the URL of the location.
class SoapClient8083 extends SoapClient
{
public function __doRequest($request, $location, $action, $version, $one_way = 0) {
$location_parts = explode("//", $location);
if (count($location_parts) == 2) {
$location_url_parts = explode("/", $location_parts[1]);
$location_url_parts[0] .= ":8083";
$new_location = $location_parts[0] . "//" . implode("/", $location_url_parts);
}
if (isset($new_location) && $new_location)
$location = $new_location;
return parent::__doRequest($request, $location, $action, $version, $one_way);
}
}
So it was getting the function list from the correct place which was why it was correctly recognising when I removed the function, but then contacting the wrong place to actually implement the functions.
... 8 hours of trying to debug later ...
Anyway, I'd rather not stick with this solution and instead figure out why the WSDL doesn't put the port number on the <soap:address location... />
Thanks for the responses - they did encourage me to look in the right direction...

Related

Stuck with woocommerce_rest_authentication_error: Invalid signature - provided signature does not match

Below issue was posted by me on https://github.com/XiaoFaye/WooCommerce.NET/issues/414 but since this may not be related at all to WooCommerce.Net but on a lowerlevel to Apache/Word/WooCommerc itself I am posting the same question here
I am really stuck with the famous error:
WebException: {"code":"woocommerce_rest_authentication_error","message":"Invalid signature - provided signature does not match.","data":{"status":401}}
FYI:
I have two wordpress instance running. One on my local machine and one on a remote server. The remote server is, as my local machine, in our company's LAN
I am running WAMP on both machines to run Apache and host Wordpress on port 80
The error ONLY occurs when trying to call the Rest api on the remote server. Connecting to the local rest api, the Rest Api/WooCommerceNet is working like a charm :-)
From my local browser I can login to the remote WooCommerce instance without any problem
On the remote server I have defined WP_SITEURL as 'http://[ip address]/webshop/ and WP_HOME as 'http://[ip address]/webshopin wp-config.php
Calling the api url (http://[ip address]/webshop/wp-json/wc/v3/) from my local browser works OK. I get the normal JSON response
Authentication is done through the WooCommerce.Net wrapper which only requires a consumer key, consumer secret and the api url. I am sure I am using the right consumer key and secret and the proper api url http://[ip address]/webshop/wp-json/wc/v3/ (see previous bullet)
I already played around with the authorizedHeader variable (true/false) when instantiating a WooCommerce RestApi but this has no effect
Is there anybody that can point me into the direction of a solution?
Your help will be much appreciated!
In my case, the problem was in my url adress. The URL Adress had two // begin wp-json
Url Before the solution: http://localhost:8080/wordpress//wp-json/wc/v3/
URL Now, and works ok: http://localhost:8080/wordpress/wp-json/wc/v3/
I use with this sentence.
RestAPI rest = new RestAPI(cUrlApi, Funciones.CK, Funciones.CS,false);
WCObject wc = new WCObject(rest);
var lstWooCategorias = await wc.Category.GetAll();
I hope my answer helps you.
Had the same issue. My fault was to define my url incorrect: http:// instead of https://.

Why would a callback URL not work (for a GroupMe bot)?

I am creating a GroupMe bot, and I'm testing out the callback URL and the basic WSGI app I've set up so far. I am planning host the bot on Heroku, but am testing it on my local machine first. I registered a bot, with the callback URL http://MY_IP_ADDRESS:8000. When I open a different shell and run requests.post('http://MY_IP_ADDRESS:8000', data = 'something') in the Python interpreter, everything works fine. However, when there is activity in the GroupMe group, nothing happens, not even an error message.
Here's my (simplified) code:
from wsgiref.simple_server import make_serve
def app(environ, startResponse):
try:
requestBodySize = int(environ.get('CONTENT_LENGTH', 0))
except ValueError:
requestBodySize = 0
# requestBody = environ['wsgi.input'].read(requestBodySize)
print('something')
responseBody = bytes('successful', 'utf-8')
status = '200 OK'
responseHeaders = [('Content-Type', 'text/plain'), ('Content-Length', str(len(responseBody)))]
startResponse(status, responseHeaders)
return [responseBody]
server = make_server('', 8000, app)
server.serve_forever()
I'm sure I'm doing something obvious, but I can't for the life of me figure out what. I'd appreciate any help!
I never figured out why the callback URL wasn't working with localhost, but when I deployed the app on Heroku, everything worked fine! It must have had something to do with my firewall settings.
When you run servers on your local machine your firewall doesn't really like that. GroupMe also cant send to anything but public facing addressees, which is why Heroku works. One thing I can recommend in the future is using Ngrok, https://ngrok.com/ this will work with your server to make a public facing address on your machine that you can use as callback url. I use Ngrok to test my bots and quickly iterate before pushing to a dedicated server like Heroku, honestly looking through Heroku log files is a pain...

Passing hostname to Invoke-WebRequest to warm up web application

I'm trying to generate requests to fire at our new versions of our .net web apps in IIS in order to start the app pools and warm them up.
The different versions are bound to local IPs and I'm trying to hit them with the following request as it looks like it will do the job:
Invoke-WebRequest 'http://172.28.36.31' -Headers #{host="www.mydomain.com"}
Now got the above working.
Any ideas on getting the same request to work over https and ignore and self signed cert warnings? There's a couple of options to ignore the warnings but haven't seen anything to use an ip with a custom host (akin to a local host entry)
You are getting a non-success http status code from the server which makes PowerShell throw an exception. Based on the "Object moved to here" message I assume it's going to be a redirect response.
You can check the status code by modifying your call like this:
try {
$response = Invoke-WebRequest 'http://172.28.36.31' -Headers #{host="www.mydomain.com"}
} catch {
$_.Exception.Response.StatusCode.Value__
}

IdentityModel.OidcClient library doesn't seem to work with UWP

We are using ASP.NET Identity with IdentityServer4. We've added a Client to use with Azure AD. This works great within a web page, that part is working.
Our end goal is a UWP app, so we found the IdentityModel.OidcClient which has a UWP sample. This sample has two browser classes. We configured HTTPS, but the WabBrowser class now refuses to connect to the site at all. If I change the config to hit https://demo.identityserver.io then it works, but all the other config is the same, so I'm not sure what the problem could be. It shows an error message in the pop up browser that it could not connect.
I looked at the SystemBrowser class, but this logs in fine, then the browser window does not close, and even if we close it, the code doesn't move on to get back a result. Looking at the source, this is not surprising, it calls:
Launcher.LaunchUriAsync(new Uri(options.StartUrl));
and that's all. The RedirectUri is not passed in, and mechanism appears to exist to use it. So, the behaviour we see appears to be the extent of what the class can do.
Looking at the console .NET Core sample, it has a SystemBrowser class that works. I updated the UWP sample to use the Fall Creators Update and was able to bring in the ASP.NET Core dlls needed to compile this code. It sets up a class like this:
public LoopbackHttpListener(int port, string path = null)
{
path = path ?? String.Empty;
if (path.StartsWith("/")) path = path.Substring(1);
_url = $"http://127.0.0.1:{port}/{path}";
_host = new WebHostBuilder()
.UseKestrel()
.UseUrls(_url)
.Configure(Configure)
.Build();
_host.Start();
}
and I can confirm this gets called only once, but even if I hard code an unused IP address, I get an error that the IP is in use.
So, at this stage, the sample that exists for UWP works for the demo server but not for ours (I suspect an HTTPS issue, but that's not the error I get), and importing code that works for a Core sample, does not work either. I've spent a couple of days on this and would appreciate a nudge in the right direction.
So, to recap, the WabBrowser seems the best bet but, for my localhost IdentityServer I get this:
and if I try to use a .NET Core library that works elsewhere, it thinks a port is in use. I suspect I need to work out why WabBrowser can't connect to my local site. I have turned off Fiddler. I can browse to my https URL and get a disco document, in the browser, at https://localhost:44305/.well-known/openid-configuration.
There are extra steps necessary to enable localhost in the Web Authentication Broker -
https://msdn.microsoft.com/en-us/library/windows/desktop/jj658959%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
This website gave me the fix. Here is a synopsis:
Remove loopback isolation
For security and reliability reasons, UWP applications are not allowed to send requests to the loopback interface. While Visual Studio automatically creates exemptions for debugged apps, this feature won't be helpful in this case, as the authentication broker always executes in a separate process.
If you see this (cryptic) error message in your Windows event logs, then you're likely facing this issue:
AuthHost encountered a navigation error at URL: [...] with StatusCode: 0x800C0005.
One option to fix it is to use the loopack exemption utility developed by Eric Lawrence. It's natively included in Fiddler 4 but can also be downloaded as a standalone software. To allow the authentication broker to communicate with the loopback interface, exempt the applications starting with microsoft.windows.authhost and save your changes:
If everything was properly configured, you should now see the login/consent page returned by your server.

Creating a url in controller in asp.net mvc 4

I am trying to send activation mail to the currently registered user.In mail body,I need to send a link like http://example.com/account/activation?username=d&email=g.Now, for debugging on local machine, I manually write it as localhost:30995/account/activation?username=d&email=g. But, when my port number changes, I need to rewrite it.
I tried another question
on this website,but, compiler gives error like url.action doesnot exist.
Please give me fresh solution as I am confused with that solution.
Use a Url.Action overload that takes a protocol parameter to generate your URLs:
Url.Action("Activation", "Account", new { username = "d", email = "g" }, "http")
This generates an absolute URL rather than a relative one. The protocol can be either "http" or "https". So this will return http://localhost:XXXXX/account/activation?username=d&email=g on your local machine, and http://example.com/account/activation?username=d&email=g on production.
In short, this will stick whatever domain you're hosting your app on in front of your URL; you can then change your hostname/port number/domain name as many times as you want. Your links will always point to the host they originated from. That should solve the problem you're facing.
Try using IIS / IIS-Express instead of Casinni web server that comes with visual studio.
You could add bindings to have the right URL (with host entries of course).
This will avoid the port numbers in your links.

Resources