"maximum string content length quota (8192) has been exceeded while reading XML data" calling WCF via mexAddress moniker - asp.net

I'm attempting to call a WCF service via mex from a classic ASP page. I've got the call working using the details on MSDN, but if I pass back an amount of data exceeding 8K I get an exception stating:
The maximum string content length
quota (8192) has been exceeded while
reading XML data. This quota may be
increased by changing the
MaxStringContentLength property on the
XmlDictionaryReaderQuotas object used
when creating the XML reader...
The fix for this is easy enough in .NET client: you can adjust the client config to having a binding with a readerQuotas section including an increased quota. However, since I'm building a service moniker to pass to a GetObject call within ASP, I don't have access to a config to edit. If it were a VB6 app, I could use dllhost.exe.config, but that's not the case. The bindingConfiguration node (and sub nodes) don't appear to be parameters I can set within the moniker string.
Any ideas on how I could influence this parameter within the ASP context? ASP snippet with moniker string referenced below:
Dim strXml, moniker, objProxy
moniker="service:mexAddress='http://localhost/SomeApp/SomeServices/SomeService.svc/mex', "
moniker=moniker + "address='http://localhost/SomeApp/SomeServices/SomeService.svc',"
moniker=moniker + "contract=ISomeService, contractNamespace=http://foo.com, "
moniker=moniker + "binding=WSHttpBinding_ISomeService, bindingNamespace=http://foo.com"
Set objProxy = GetObject(moniker)
strXml = objProxy.DoWork("foo", "bar")
Thanks!

Try setting your maxStringContentLength in your wcf binding configuration on the server side.

It's my understanding that the service:mexAddress moniker actually uses a WCF client behind the COM interface. If that is the case then you can store the WCF config in a file called «foo».exe.config, where «foo» is replaced by the name of the executable.
If you are running the ASP within IIS6 or IIS7, then the EXE that runs the ASP is probably w3wp.exe, which means you need to drop the config into a file called w3wp.exe.config , located in the directory c:\Windows\system32\inetsrv.

Related

ASP Classic can I use Response.AppendToLog in global.asa Application_onStart

In ASP Classic can i use Response.AppendToLog in global.asa Application_onStart ?
I would try to Log error when application starts, but i always get this error:
erreur '8002802b'
/v1/common/CAppInit.asp, line 21
line 21:
Response.AppendToLog "INIT DB ERROR"
You can’t use the Response object in the global.asa file because there is no context for a response. The global.asa file deals with Application and Session level context.
If you think about it, when the application starts there doesn’t need to be a response because there is no initial request, it operates entirely outside of that pipeline.
The definition of the Response.AppendToLog() method is as follows;
The AppendToLog method adds a string to the end of the Web server log entry for the request.
This means that an initial request is required, which makes using it in the context of application startup impossible.
The usual solution is to implement a custom logging function that can be utilised inside the context of the Application or Session startup events.

Could not find default endpoint element that references contract 'Service' error in consuming web Services in asp.net mvc

I have a problem when calling web Services in ASP.net MVC , I do the following
add the web service by add service reference to solution, and I include the service.cs file to the solution also, but when I try to create object in home controller , I have the following error
Could not find default endpoint element that references contract 'Service' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
can any one help me please
thanks
There's a couple things going on here. First, you're using SVCUTIL to generate a proxy and configuration settings for a non-WCF service - .asmx is legacy. I was able to generate a proxy and config settings, but to overcome the error you got you need to call one of the overloaded versions of WeatherHttpClient.
I'm not 100% sure, but this is what I think based on what I observed.
The reason is because there are two endpoints defined in the configuration file (one for SOAP 1.1 and one for SOAP 1.2), and since both endpoints are named there is no default endpoint to choose from.
When I used var x = new WeatherHttpClient(new BasicHttpBinding("WeatherSoap"), new EndpointAddress("http://wsf.cdyne.com/WeatherWS/Weather.asmx")); I was able to create the proxy just fine.
However, when I called GetCityForecastByZip I got the following error:
Server did not recognize the value of HTTP Header SOAPAction: http://ws.cdyne.com/WeatherWS/WeatherHttpGet/GetCityForecastByZIPRequest.
So then I used WSDL.exe to generate the proxy a la .ASMX style. I included that in my project, and the following code returned a result (after including a reference to System.Web.Services - I was using a console app):
var x = new Weather();
ForecastReturn result = x.GetCityForecastByZip("91504");`
I would suggest for simplicity using WSDL.exe to generate the proxy for your service, as it seems to be simpler.
I will also add that I've done very little MVC, but I don't think this is an MVC issue. I hope this helps you.

Consuming a Web Service from a Class Library

Using Visual Studio I have a Class Library (C#) where I added a reference to a Service (more preciselly a Web Service).
The Web Service classes and interfaces where generated correctly, and I am trying to consume them using the following code (the web service receives an returns a string):
CallWS request = new CallWS();
request.input = "input string";
WSClient client = new WSClient();
CallWSResponse response = client.CallWS(request);
The last line originates the following exception:
Could not find default endpoint element that references contract 'WS_INTER' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
How do I solve this?
You have to add an application configuration file and set up system.serviceModel section defining the address of a service.
You can certainly do that in code. Check this or MSDN for description

IIS7 Application Request Routing (arr reverse proxy) combined with managed module - time out

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

How do I get the host domain name in ASP .NET without using HttpContext.Current.Request?

I've got an ASP .Net application running on IIS7. I'm using the current url that the site is running under to set some static properties on a class in my application. To do this, I'm getting the domain name using this (insde the class's static constructor):
var host = HttpContext.Current.Request.Url.Host;
And it works fine on my dev machine (windows XP / Cassini). However, when I deploy to IIS7, I get an exception: "Request is not available in this context".
I'm guessing this is because I'm using this code in the static constructor of an object, which is getting executed in IIS before any requests come in; and Cassini doesn't trigger the static constructor until a request happens. Now, I didn't originally like the idea of pulling the domain name from the Request for this very reason, but it was the only place I found it =)
So, does anyone know of another place that I can get the host domain name? I'm assuming that ASP .Net has got to be aware of it at some level independent of HttpRequests, I just don't know how to access it.
The reason that the domain is in the request is...that's what's being asked for. For example these are a few stackexchange sites from http://www.stackexchangesites.com/:
http://community.ecoanswers.com
http://www.appqanda.com
http://www.irosetta.com/
If you ping them, you'll see they all point to the same IP/Web Server and be served by the same app (or multiple apps in this case, but the example holds if it was one big one)...but the application doesn't know which one until a host header comes in with the request asking the server for that site. Each request may be to a different domain...so the application doesn't know it.
If however it doesn't change, you could store it as an appSetting in the web.config.
Use global.asax or write a HttpModule and subscribe to start request events. You will have the request passed into your event handler.
Use this instead:
HttpRuntime.AppDomainAppVirtualPath
Or if you want the physical path:
HttpRuntime.AppDomainAppPath
For further reading:
http://weblogs.asp.net/reganschroder/archive/2008/07/25/iis7-integrated-mode-request-is-not-available-in-this-context-exception-in-application-start.aspx

Resources