So, I'm trying to use soap to communicate with a webservice and getting errors. What is frustrating about this particular issue is that it works perfectly fine with my local copy of the webservice (yes, I tried turning off my firewall) and used to work fine with a previous version of the webservice and client. I suspect I could (though I'll have to look up how to do this) add an action parameter to what the client is sending. However, I am very curious why it was able to work previously without one.
Edit Clarification: I think the relevant code was the same between when it stopped working and when it worked (since I checked against an old version of the program and had the same problems and the relevant code was the same...unless I missed something subtle). I know the actual server program is the same on both the local copy and the remote copy, even though it only works locally. I thus suspect there is some sort of weird configuration setting I can change to make it work.
Error message: "soap:ClientUnable to handle request without a valid action parameter. Please supply a valid soap action."
VB Client Code
'WEB_SERVICE_URL_CONST = http://site.com/foo.asmx
'domDoc.xml = <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><TestConnection xmlns="http://site.com"/></soap:Body></soap:Envelope>
Dim oXml As New XMLHTTPRequest
oXml.Open "POST", WEB_SERVICE_URL_CONST, False, "\"
oXml.setRequestHeader "Content-Type", "text/xml"
oXml.send domDoc.xml
C# Server Code
[WebMethod]
public int TestConnection()
{
return 1;
}
Are you sure the first two lines are not commented-out in the real version? The sample code seems to have no value for WEB_SERVICE_URL_CONST and domDoc.xml, and an empty Soap request would indeed not specify any action?
EDIT: I find the "used to work fine with a previous version of the webservice and client" a bit confusing. If you actually changed both the client and the server, then what part did not change?
The problem was with the xmlns="http://site.com" code. When I tested locally, I was using xmlns="http://localhost" by mistake. In fact, this should not be changed on the client or the server (in the server, this would be WebService(Namespace =...)), regardless of where I am testing...but if it does change, the client and server need to match.
Related
I am trying to create a method in a class that accesses a WebMethod on a Web Service using WebClient, and am running into problems. Using VS2010 on Windows.
First of all, yes I know I could create a Web Reference to the web service in the class library, of course this is design time binding. However, I need to be able to get to the web service using information only available at run time. There's a business reason for this that I won't go into here, just go with it, please.
This appears to be possible using the WebClient class from the System.Net namespace. And in fact I am able to get to the service in question, but the data I am sending to it doesn't appear to be in a correct format, although for all I can tell it is a properly formatted SOAP message.
The WebException contains the following message: "The remote server returned an error: (415) Unsupported Media Type."
Here's the code:
public string DoingBusiness()
{
WebClient client = new WebClient();
string destUri = "http://localhost/Service/Service.asmx?op=CommunicationsCheck";
StreamReader reader = new StreamReader(#"CommCheck.xml");
string data = String.Format(reader.ReadToEnd(), "The End is Near!");
reader.Close();
string response = client.UploadString(destUri, data);
return response;
}
Leaving off the actual xmlns, which is sensitive, the data read by the StreamReader above looks like:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<CommunicationsCheck xmlns="http://.../">
<communication>{0}</communication>
</CommunicationsCheck>
</soap:Body>
</soap:Envelope>
This looks like a perfectly fine SOAP message. Of course the "{0}" gets filled in with the payload string. If the WebMethod "CommunicationsCheck(string communication) ran successfully it would return:
<?xml version="1.0" encoding="utf-8" ?>
<string xmlns="http://[service url]/">You sent 'The End is Near!'</string>
Which it does if I access the service through a browser, or through a design-time web reference.
So, the question is, what am I doing wrong here that I get the "(415) Unsupported Media Type"
Are there properties on the WebClient that need to be set? Do I perhaps need to provide a Header containing a UserAgent? Or something else?
Darn. I guess I should let someone else answer the question, but answering one's own question is acceptable, if one finds it oneself.
Anyway, some further research on the problem seemed to suggest that one surmise on my part, namely that there might be some Header property I needed to set, was a possible solution. And the research suggested that the property would be "content-type" needed to be set as "text/xml". So I added this line:
client.Headers.Add("content-type", "text/xml");
just before the UploadString method call.
BINGO!
The expected response occurred.
Has anyone ever noticed that answers to perplexing questions sometimes become self-evident once the question is posed, but not before? Interesting phenomenon.
I have an https .net webservice. Invoking web methods using tools like soap UI works fine. I am unable to invoke the webmethod from flex. My WSDL loads up fine in flex.
On deployment my flex application and the webservice are on the same server. When use the machine url and access from within the server it works fine, but not when I use the https url for the flex application.
Eg - http://machinename/flex/flexApp.html works fine with https://publicname/wservice/ws.asmx but https://publicname/flex/flexapp.html fails to work.
I have the crossdomain policy in place with full access and also I have a valid SSL certificate on the server.
When I make the call from my local machine in debug mode I see the following in Fiddler-
The WSDL call goes fine and returns back correctly and the Protocol is shown as HTTPS where as the webmethod call following it shows the protocol as HTTP and returns back with the error -
I have been stuck on this for quite some time. Any help is greatly appreciated.
Thanks,
Nikhil.
Here is my Flex code that calls it:
//business delegate
public function BusinessDelegate(responder : IResponder):void
{
_responder = responder;
_service = ServiceLocator.getInstance().getService("sqlWebService");
_service.loadWSDL();
}
//Login User
public function Login(userId:String,password:String):void
{
var asyncToken:AsyncToken = _service.LoginUser(userId,password);
asyncToken.addResponder(_responder);
}
and the service locator has the following tag where I set the URL from outside as https://....
<mx:WebService
id="sqlWebService"
useProxy="false"
concurrency="multiple"
showBusyCursor="true"
wsdl="{Url}"/>
I finally was able to resolve this problem by replacing the code where I call the Flex WebService object with the specific generated classes for the webservice.
I generated classes for the webservice using Import WebService(WSDL) and was setting the url on the main class on run time as https://.....
and it works like a charm...and I see that in fiddler it shows me correctly going out as HTTPS instead of the HTTP.
Here is what helped me -
http://livedocs.adobe.com/flex/3/html/help.html?content=security2_15.html
Comment by nated.
Thanks Flextras.com for pointing me to right direction.
Resolved.
If using WCF service and WebService in Flex, use
service.svc?wsdl for HTTP and
service.svc/wsdl?wsdl for HTTPS,
I am trying to build a proxy that would serve requests to an internal site (hiding the origin) but at the same time inspect the packets and asynchronously post-process them.
E.g. let's say all SOAP calls to http://www.foo.com will go to http://192.168.1.1, and at the same time be stored in a DB for post analysis. The internal server is a black box, so changing something on it is out of this question scope.
Anyway, I have configured ARR, with reverse proxy, made URL rewrite filter with wildcards, all works flawless. Then, I tried to add an managed HttpModule written in C#, and hooked to Application_BeginRequest and Application_EndRequest. I am able to access request headers, response headers on end request (app pool being in integrated mode) and even able to read response content from the outputstream by setting a filter on Response.Filter, that caches all writes in an additional memory stream.
The problem is that the moment I try to read (inside the module BeginRequest handler) the input stream from the request, ARR stays a while and throws a
HTTP Error 502.3 - Bad Gateway The
operation timed out Handler
ApplicationRequestRoutingHandler
Error Code 0x80072ee2
So it times out.
Looking with Failed Request Tracing I see:
MODULE_SET_RESPONSE_ERROR_STATUS
Warning
ModuleName="ApplicationRequestRouting",
Notification="EXECUTE_REQUEST_HANDLER",
HttpStatus="502", HttpReason="Bad
Gateway", HttpSubStatus="3",
ErrorCode="2147954402",
ConfigExceptionInfo=""
SET_RESPONSE_ERROR_DESCRIPTION Warning
ErrorDescription="The operation timed
out"
Now any similar posts on the net didn't helped as this isn't a timeout error (proxy has 120 seconds setting, page answers in under 100 ms), and the moment I comment the code of the handler that tries to read FORM data or InputStream data, everything works as a charm.
Even if I set the position of the inputstream to 0 after reading it, I still get timeouts.
If I read the input stream on EndRequest, it gets 0 bytes, even if it was a POST request. (which is clearly wrong)
Does ARR has a bug in the fact that I try to read an input stream before it tries to re-route it?
Things used: Windows Server 2008 R2
IIS 7.5 ARR v2 .Net Framework 3.5
module
Ideas?
Thanks
/Cosmin
If you can switch to .Net Framework 4, there is a solution for this.
After you are done with your BeginRequest/EndRequest in your HttpModule event handler, add a call to HttpRequest.InsertEntityBody.
/* BeginRequest event: Executes before request is processed */
private void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpRequest request = application.Context.Request;
// Do something with request
DoMyOwnRequestProcessing(request);
// After you finish, make sure IIS gets the entity body
// For example, Application Request Routing needs this
request.InsertEntityBody();
}
Take a look at this on MSDN: HttpRequest.InsertEntityBody.
I know this is a year old question, but I just went through the same thing and found a solution. So, I'm posting it here for anyone else that runs into this.
In my case I only saw the timeout issue with POST requests.
It appears that the 2.0/2.1 ARR assumes that the input stream will be at the start of the posted data. However, the following code (for example) will break this assumption:
HttpContext context = HttpContext.Current;
HttpRequest request = context.Request;
string value = request.Params["Name"];
The key is how Params is described
Gets a combined collection of System.Web.HttpRequest.QueryString,
System.Web.HttpRequest.Form, System.Web.HttpRequest.ServerVariables,
and System.Web.HttpRequest.Cookies items."`
When the request is a POST, accessing Params will read the posted data from the input stream, invalidating ARR's assumption. As will reading from the input stream.
I knew the data I needed was in the query string, not the posted data, so I worked around this by accessing the QueryString instead of Params. This avoids reading the posted data and works fine for me.
string value = request.QueryString["Name"];
This issue appears to be fixed in ARR 2.5.
Upgrading ARR appears to be the only solution if you need to access posted data before handing off to ARR. The key is to let HttpRequest handle acquiring the data into Params. If you read it directly it will not work.
I just ran into this bug and your experiences helped me determine the root cause.
My main server is MVC based and it looks at the Request.Form values in the Application_BeginRequest method. If the form values are accessed ARR fails to forward the body of a HTTP POST request. GET requests will work fine since there is no body.
I have routes.IgnoreRoute ("Forum/{*pathInfo}"); as a registered route but ARR runs as a HttpModule and doesn't kick-in until later in the pipeline. That means my MVC based application is given the opportunity to access the content of the POST body which somehow prevents ARR from accessing the body itself and forwarding it to the proxy'd server.
Here is Cosmin's related post on the iis.net forums: ARR 2.0 BUG - combined with managed http module timeout on read inputstream
In my application I have all myserver.com/Forum/* requests being reverse proxy'd to a separate application on another server. So I simply checked the HttpContext.Current.Request.Url in my MVC application's Application_BeginRequest method to make sure it does not contain /Forum before accessing the Request.Form values. Once I did that the POST bodies made it through ARR just fine.
UPDATE: after further testing it appears that there are still problems with ARR as POST from non-authenticated users still fails. Instead of the main website being MVC I created a dummy IIS .NET 4.0 website with a single Default.html document. But I still ran into problems with POST requests and ARR. Then I switch the application pool to ASP.NET 2.0 and what do you know, it works. At this point I have to assume that something in the .NET 4.0 pipeline is accessing the input stream which prevents ARR from accessing the input stream itself in order to forward the POST body.
按照正常来说,再iis网站界面会有一个application request
routing cache 的 icon, 可以点击 设置timeout 但是这里没有显示
找到了 官方说明可以用命令行解决这个问题
https://blogs.iis.net/richma/502-3-bad-gateway-the-operation-timed-out-with-iis-application-request-routing-arr
blogs.iis.net
执行以下命令,然后重启下网站服务
进入到C:\Windows\System32\inetsrv 打开管理员命令行工具执行以下命令
appcmd.exe set config -section:system.webServer/proxy /timeout:"00:00:45" /commit:apphost
重启下网站服务
我写的原文地址
https://zhuanlan.zhihu.com/p/157557980
Problem: I've got an ASP.NET website and i don't believe that my code is getting OutputCached correctly. I'm using IIS7 performance counters to show me the hits or misses a second.
i've got a simple ASP.NET MVC website. I'm using the built in ASP.NET Output Cache magic.
Here's some sample code :-
[AcceptVerbs(HttpVerbs.Get)]
[ApiAuthorize] // <-- this checks the querystring for a "key=1234".
// Doesn't find it, then it throws a 401 NOT AUTH exception.
[OutputCache(CacheProfile = "HomeController_Foo")]
public ActionResult Foo(string name, byte? alpha, byte? beta)
{
}
so this means that each url query can be like the following :-
http://www.mydomain.com/Foo?name=hello+word&key=1234
http://www.mydomain.com/Foo?name=hello+word&alpha=1&key=1234
http://www.mydomain.com/Foo?name=hello+word&alpha=1&beta=2&key=1234
Now, notice how i've got the OutputCache referencing a config file? here it is...
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="HomeController_Foo" duration="3600" varyByParam="key;name;alpha;beta"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
Nothing too hard ...
so here's the kicker! When I confirm that this is happening by using the IIS7 performance counters, it's saying that the output cache misses/sec are 100% of the requests i'm making a sec. Output cache hits are 0/sec.
I'm using a 3rd party web load stress testing program to bast my site with queries. Now, what's the source data? a list of names. The program keeps looping through all the names, then goes back to the start, rinse repeat. So it's BOUND to call the same query string at least once. IIS log files confirm this.
I'm not passing in any data for the alpha or beta.
this is my query string i'm hitting....
http://www.mydomain.com/Foo?name=hello+word&key=1234
... where i keep substituting the 'hello+world' with the names from the data source file and IIS logs confirm this.
So .. am i looking at the wrong performance counter? Are there any other tricks to see if it's getting outputcached? The code is very fast, so it's hard to tell if that is a cached result or not.
Probably way too late but to help others : If you had a cookie in your response header, that will prevent it from being cached. The outputcache (http) module has a lot of silent check to ensure the response is subject to being cached. Looking into it through reflection might give anyone candidate of failure to put in cache.
Use a tool like firebug and look at the response from the request. You'll be able to tell by the 200 or 304 whether the cache response was used (304) or if a successful response was sent (200).
I'm working on two websites. One is an existing classic asp site which posts xml to a new asp.net (.net 3.5) website. The classic asp site is using msxml's serverxmlhttp object in vbscript to send this xml over. The whole thing works until I make a seemingly unrelated change to the asp.net site.
When I add a few lines of code that uses System.Speech.Synthesis to generate a wav file from text the classic asp websites serverxmlhttp.send command times out. As far as I can tell the asp.net page is working fine, it makes it through the few new lines of code without an issue (the wav file is generated). The few lines of speech code causing the issue is done well before the timeout.
It seems like the asp.net page was actually sending some sort of acknowledgement back to the classic page which is no longer getting sent. I should also point out that the speech code was throwing an exception saying it needed to be asynchronous which I fixed by adding Async="true" to the . However, it works when async="true", it's just those speech lines that break it. The "problem code" is just
SpeechSynthesizer speaker = new SpeechSynthesizer();
speaker.Volume = 100;
speaker.SelectVoiceByHints(System.Speech.Synthesis.VoiceGender.Female, System.Speech.Synthesis.VoiceAge.Adult, 0);
try
{
speaker.SetOutputToWaveFile("c:\\test\\output.wav");
}
catch (Exception ex)
{
retVal = false;
}
speaker.Speak(msgText);
speaker.SetOutputToDefaultAudioDevice();
Does anyone have any suggestions on what could be wrong or what I could use to help debug this?
It seems like the asp.net page was actually sending some sort of acknowledgement back to the classic page which is no longer getting sent
It sounds like you should investigate it more so you can tell us server's response behavior before and after. Also please indicate the exception thrown.
My guess would be these APIs don't work well in a service process. I have no clue though really. I'm curious about the exception, you're not clear about what you made async.