I am adding headers to a page as follows:
Page.Response.AddHeader("foo", "bar");
Depending upon previous processing, sometimes this fails with "Server cannot append header after HTTP headers have been sent." I am dealing with this by enclosing Page.Response.AddHeader("foo", "bar"); within a try-catch construct. However, to keep things cleaner and avoid generating an exception is there any way to detect that the headers have already been sent? (btw if I try evaluating Page.Response.Headers then I get the following error: "This operation requires IIS integrated pipeline mode")
Thanks
As of .NET 4.5.2, you can do this using the now-public HeadersWritten property of HttpResponse (see the msdn docs):
if (HttpContext.Current.Response.HeadersWritten) { ... }
You can use an HttpModule to register for the PreSendRequestHeaders event. When it gets called, write a value to HttpContext.Current.Items indicating that the headers are being sent – and then everywhere else in your code you check the value in HttpContext.Current.Items to see if its been sent yet.
UPDATE: the HeadersWritten property is now available on the HttpResponse object.
Unfortunately, whilst the HttpResponse object has a property called HeadersWritten, and a backing field called _headersWritten, neither of these are accessible from outside of the System.Web assembly - unless you use Reflection. I'm not clear what you think you'll be able to obtain from the Headers collection, it may or may not exist, independently of whether the headers have been sent yet.
If you want to use Reflection, it may have it's own performance penalties, and it will require your application to run in full trust.
All of the publicly accessible methods on HttpResponse that involve the _headersWritten field seem to use it to throw an exception.
Trying setting buffer to false:
http://msdn.microsoft.com/en-us/library/950xf363.aspx
This will alleviate your first problem but your perfromance and user experience can suffer.
Also "This operation requires IIS integrated pipeline mode" is related to non-IIS 7 server processing that line of code. You can find more info on it here:
http://forums.asp.net/p/1253457/2323117.aspx
Related
Our error logger is picking up the following error periodically:
System.InvalidOperationException: Request format is unrecognized for
URL unexpectedly ending in '/TheMethodName'
The reason this error is being thrown is because the request to the script service is using the GET method, and the default security settings only allow POST requests.
The strange part is that the only place in our code where we are calling this particular service method is through an $.ajax call, and it is specifically using type: 'POST'. There is no other place in the app where a GET request is made for this service.
The ui is making the POST call every 20 seconds to retrieve some data, and it does not seem that the GET's are interfering with that -- they are just extraneous. I've looked at the IIS logs, and I can see the proper POST requests, and then sometimes a GET request.
As an added wrinkle, it's not just this web service that is getting the extra GET calls -- we are logging these to several other service endpoints as well.
My guess is that the browser or a proxy server or something is making these calls on its own (like as part of prefetching or some sort of caching), but I have no evidence of that. In looking at the user agent for the bad requests, they are coming in from a variety of browsers.
Has anybody else seen this before, or have an idea of what might be causing it?
I have some functionality in the code behind, which after executing needs to forward the request to another page. I want to pass along data like you would by setting a request attribute in Java (i.e. - I don't want it in the query string of the redirected response). Is this possible with ASP.NET (c#)?
You can use Server.Transfer if you want to forward the request and keep all of the Request variables, or you can use Session.
Are you using ASP.NET Webforms or MVC? The following will redirect your request to a new page. You'll have to test and see if it forwards post data (I'm not sure). Now that you mention it, I don't think ASP.NET has a built in "forward:" request like java does. I think it just has "redirect" for security reasons. (Someone correct me if I'm wrong).
In Webforms:
try Response.Redirect("mynewpage").
In MVC:
at the completion of your action method return Redirect("mynewpage")
I don't know your use case, but it is generally not good practice to pass post data to a different page/request. Typically the posted action will take care of persistence, and then a GET request will be issued to the redirect page. If the redirected view needs access to the posted data, it should go to the persistence mechanism (DB) to retrieve it. This method is more secure, and generally better practice. This is a very general guideline, so use it as your needs allow.
HTH
Yes - See the reflection code at:
HttpModule to add headers to request
However - the question is - do you really want to use request headers? probably not. its a hack to use them. If you simply want to pass information, use the Context.Items dictionary to transfer your items between requests with Server.Transfer.
Depending on what you are doing and where your events are, you can also make use of Cross Page Postback.
See http://msdn.microsoft.com/en-us/library/ms178139.aspx
Otherwise, I'd go with vcsjones answer of Server.Transfer
I develop an asmx web service (i.e. ASP.NET 2.0).
There's a piece of code that may read the contents of the HTTP request (via HttpContext.Current.Request.InputStream) while processing it. I realise that InputStream may only be read once for a request, and I make sure I never try to read it more than once.
The problem seems to be that if InputStream happens to be read during the early stages of the application's lifecycle (e.g. after pskill w3wp, during Application_Start), the HTTP request fails with a HTTP 400 - Bad Request error, with no explanation given, no exception thrown and no entry in the httperr log. If it is read later (e.g. within the web method itself), requests run fine whether InputStream is read or not. Application_Start runs fine if InputStream isn't read.
Is this some sort of ASP.NET bug? IIS bug? Or am I doing something wrong by daring to read InputStream? And if so, is there another way to get a look at the "raw" contents of the request without disturbing the inner workings of IIS/ASP.NET?
In short, adding this code within Application_Start is enough to reproduce this error:
using (StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream))
reader.ReadToEnd();
Couldn't find a way to read request contents during Application_Start without disturbing inner workings of ASP.NET/IIS. Instead, ended up making sure this doesn't happen until Application_Start is over (and also doesn't happen from the moment Application_End starts, which also turned out to be problematic and created access violations).
You have to no use the using bloc because this has as effect to close the reader and by consequence to close the inputstream of httprequest
I would suggest not attempting to read the Request.InputStream during Application_Start - it's used for initialising the application. Accessing the Request object from within Application_Start results in an exception "Request is not available in this context."
The fact that you are wanting to read the input stream suggests you should be using Application_BeginRequest instead - this has access to request and response.
In Summary:
Application_Start
Fires once when the application starts. While usually triggered by the first request, it occurs before the first request is set up. Don't do request specific code in here as it doesn't have access to Request and Response.
Application_BeginRequest
Fires for every request before any page handlers are invoked - you can read the input, write to response, end the request, etc...
See these SO articles for more info:
Request is not available in this context
Replacement for HttpContext.Current.Request.ServerVariables["SERVER_NAME"] in Integrated Mode
When does HttpRequest get created?
I am developing a RESTful framework and am deciding how to handle an unsupported verb being called against a resource. For example, someone trying to PUT to a read-only resource.
My initial thought was a 404 error, but the error is not that the resource cannot be found, it exists, just the user is trying to use the resource incorrectly. Is there a more appropriate error code? What is the most common way in which this situation is handled?
Is it that you simply don't support a certain verb ie DELETE? In that case I'd use the following HTTP response code if someone uses a verb you don't support.
405 Method Not Allowed
A request was made of a resource using a request method not supported by that resource;[2] for example, using GET on a form which requires data to be presented via POST, or using PUT on a read-only resource. [source]
I don't think you would receive a request to your app at all if the incorrect verb were used (but that probably depends on which specific technologies you're using on the server side).
To be more helpful to potentially confused client connection attempts I suppose you could create a stub endpoint/action for each commonly incorrect verb, method combinations and then send back a friendly "use {verbname} instead for this request" text response, but I'd personally just invest a bit of time in better developer documentation : )
You could also seamlessly redirect to the correct action in those cases...
I have a situation where we're aggregating what amounts to marketing data from N number of clients, where a client can host a HTML form using any backend of their choice, each with the action of the form pointing to a path that we're hosting. Each client has a different URL, there's no auth (but there is some simple validation of the data) and it's all generally working just fine.
However, there's one small wrinkle that I can't seem to get my head around.
The aspx that is processing the submitted data resides at a path, let's call it ~/submit/default.aspx. The idea is that we should be able to hand to our partner a URL along the lines of "http://sample.com/submit/?foo=bar" as the action of their form. Doing this however results in a HTTP 405 error, "Resource not allowed".
Having the action of the form set as "http://sample.com/submit/default.aspx" works just fine and dandy however.
Default.aspx is set as one of the default document names in IIS 6.
The .aspx file extension is properly mapped to the correct .Net dll and has the verbs GET, HEAd, POST, and DEBUG activated for the mapping.
Those were the only two things I could think of to double check first--anyone else have any ideas? I'd have preferred to use URL rewriting / routing with IIS7, but that's unfortunately not an option--and I have a number of additional requirements where "clean" URLs will highly be preferable, so solving this problem is going to be a pretty core problem to get through.
IIRC, IIS will only use the default docs if the requested resource is a directory. Since the requested resource in the first case is not, it'll never make it through the default doc handlers - instead failing on a POST to an unregistered script extension (405).
it may depend on the document type of "http://sample.com/submit/?foo=bar"... if you IIS doesn't know how to handle the document type being returned to it (which then returns it to you, the client), then you may get an http 405 error - which means that it doesn't know how to handle that document type, server-wise. Maybe try putting something like
in your web.config file that drives the app. HTTP Handlers are modular pieces of code, written and compiled in a .net language, and act as kind of a 'servlet' if you're familiar with Java terms. It's a piece of code that writes out something to the client -- in your case maybe a rendering of a .doc file, found programmatically in your handler class.
for some reason, it didn't render my code sample!! you guys need to decode and encode less than and greater than signs for your "Your Answer" text box.... anyways,
<httpHandlers>
<add verb="your.class.to.handle.doc.files"/>
</httpHandlers>
is what should be in your web.config file.