TransferRequest vs Transfer in ASP.Net - asp.net

I have gone through the links mentioned below,
iis forum and HttpModules & Server.Transfer / Server.TransferRequest / RewritePath problems. but unable to catch the concept behind these transfer methods.
How are they works? And which one is preferred in different situation?
Can someone explain me TransferRequest vs Transfer methods for server side transfer in asp.net and its roles?
Thanks in advance

HttpServerUtility.Transfer Terminates execution of the current page and starts execution of provided URL.
This basically maps and executes a new ASP.NET Page (or serves a static file) corresponding to the url provided. It does this in-place in the current request pipeline, without applying new configuration to the new url, or re-running IIS modules for the new url. Because of this, its very fast, but it also prevents a lot of scenarios that are possible with TRQ.
HttpServerUtility.TransferRequest Performs an asynchronous execution of the provided URL.
This is a full IIS child request under the covers, which allows it to re-run the entire request pipeline for the new request as if it was a separate request, getting the correct configuration for it, and running all of the normal IIS modules including authentication, authorization, etc. For example, IIS will apply the authorization rules for the new url, as opposed to the previous url.

TransferRequest re-runs the entire request pipeline as if it were a separate request. This means that IIS and ASP.NET modules are re-applied; authentication and authorization rules for the new URL will be honored. Note that TransferRequest requires the integrated pipeline mode of IIS 7+, and the transfer can be to an ASP page or another resource like an XML file.
Transfer transfers execution from one ASP page to another ASP page on the server. Unlike TransferRequest, IIS and ASP.NET will NOT verify that the current user is authorized to view the resource delivered by the Transfer method. If you need to force reauthorization, and integrated pipeline mode is not an option, call Redirect instead of the Transfer method. Redirect triggers a client-side redirect so that the new request will be subjected to all authentication and authorization logic of IIS and ASP.NET.

Related

Custom HttpModule is not called when used Server.Transfer

I have code in my project which changes the URL containing the text as querystring to number to get the data from the database. I am checking the querystring in page load and if it contains the name rather than the number I am mapping it to the numeric key. Now I have to execute the page life cycle again. I had two choice either use the
Response.Redirect
but I do not want the URL in the client browser to change so I went with the
Server.Transfer
The problem I started facing is that I have a custom httpmodule which is used to log the URLs in the database. I realized that
BeginRequest
in the http module is not firing after the
Server.Transfer
My application is working fine in the case of
Response.Redirect.
I am not sure how and why Server.Transfer is skipping my HttpModule and if it is how it works ?
Server.Transfer is a completely server side mechanism - it instantiates the new Page class based on the path to .aspx file and transfers the execution there (including all state information for the built-in objects). There is no new request and nothing goes again through the pipeline (so among other things HttpModules are not re-executed), as the hosting part is interested this is still the same request - the response has just been created from different page than it was originally planed.
Response.Redirect falls to standard HTTP mechanism. On server side it throws an exception to break the current execution pipeline and return an 3xx status code. The browser then issues new request for the resource under the new URL. Both requests go through full pipeline on the server side.
So the answer to your question boils down to the fact that HttpModules are being executed for every upcoming request but in case of Server.Transfer there is no new upcoming request.

Processing request URLs from browser by the .NET Framework

How does the .net framework know in what way the incoming URL is to be processed?
My question is not about routing mechanism within the application.
I want to know how the .net framework in the system finds out that it has to delegate the request to its MVC assemblies to route the URL to appropriate controller and action.
I hope the question is clear.
Just saw some other questions in stackoverflow and came across this link which somewhat explains i guess.
https://docs.google.com/file/d/0B0_EIyBZvSQsOTU3N2Q2NDEtMWNjMS00ZTc0LWJmMjUtM2I0M2I5NDY2ZDNl/edit?pli=1
This link has detailed information
http://stephenwalther.com/archive/2008/03/18/asp-net-mvc-in-depth-the-life-of-an-asp-net-mvc-request
If you host your application in IIS, then when a request comes-in, then this request is initially intercepted by IIS. Let's suppose that you hosted your application in a virtual directory called /myapp. When a request comes by starting with /myapp then IIS will handle the execution of the request to the corresponding ASP.NET pipeline. The ASP.NET pipeline will then parse the incoming request and search for corresponding managed handlers that can serve the request. If a managed handler is found that can serve the request then the processing will be passed to this handler. In the case of as ASP.NET MVC application that will be the MvcHandler which will then take care of routing and dispatching to the appropriate controller and action to serve the request.

Rewrite URL for all requests to a folder in ASP.NET 3.5 - IIS 7

We have a number of existing clients that point to urls like:
http://sub1.site.com/images/image1.jpg
/images is a virutal directory that points to a directory that actually contains image1.jpg on that server.
We're moving all of the files out of this directory and onto a separate server that will not run this same application.
The file will now only be available at:
http://sub2.site.com/image1.jpg
What is the best way to make it so clients requesting
http://sub1.site.com/images/image1.jpg will get the content that now resides at http://sub2.site.com/image1.jpg?
A few requirements:
We need the actual content to be returned through that url - not a 302 response.
We cannot modify the IIS server configuration - only the web.config for the site
Again, we're running asp.net 3.5
Thanks.
Not totally sure this would work, but you could setup URL Routing on the old site so all requests are sent to a handler and within that handler you could do a web request to get the file from it's new location.
I use a variation of the process to map image URLs to different locations and my handler does some database queries to get the mapped relationship and provide the correct image. I don't see why you could do a web request to get the image.
Since you are using IIS7, you can use the built in URL rewrite module.
You would want an inbound and an outbound rule to change \images\image1.jpg to \image1.jpg
It can get pretty involved, but this should be rather simple.
Assuming you can add handlers to your site (as in add a DLL to your /bin directory in the site) and with the restriction that you can't send 302 responses for better performance, then alternatively you could write a custom handler to grab all requests that match that URL pattern, do the web request for the sub2.site image from the original site via web client code, then serve it back out of the original site, sub1.site.com.
See How To Create an ASP.NET HTTP Handler by Using Visual C# .NET for the very basics of creating and setting up a custom handler. Then use the HttpWebRequest to make the request of sub2.site.com, as in the guide A Deeper Look at Performing HTTP Requests in an ASP.NET Page. Plus a little other code to handle errors, timeouts, passing the image through with as little processing and memory usage as possible, etc.
Depending on the response time/lag between the two servers, this may be slow, but it would fit all your requirements. But if the point of moving the images to site 2 was for performance (CPU or memory) or bandwidth limitations, then this solution would nullify any gains — and would actually make things worse. But if they were moved for other business or technical reasons though, then this solution might be helpful still.
If you have other control over the server or anything upstream from the server, you could use mod_proxy (or similar Windows/IIS tool) to intercept those URLs and forward them to another server and respond back with the real request. Depending on your network configuration and available servers, this could be the simplest, best performing solution.
Can IIS be configure to forward request to another web server? on serverfault has a quick process and link for an IIS 7.5 solution.

Accessing IIS's request handling pipeline to inject a request and get the html response

Is it at all possible to inject a request into IIS for a page, have IIS and ASP.Net handle it as normal, but get the response as html handed back to me programmatically?
Yes, I know that I could connect to port 80 using WebRequest and WebResponse, but that becomes difficult if you are accessing the IIS server from the same physical machine (loopback security controls et al).
Basically, I want to inject the request (eg for http://example.org/MyPage.aspx) between the points at which IIS would normally talk to the browser, and the point at which it would route it to the correct ASP.Net application, and get a response back from IIS between the points at which ASP.Net/IIS applies the httpfilters and hands the html back to the browser.
I'm predominantly working with IIS7 so if there is a solution that works just for IIS7 then thats not an issue.
You could implement a custom HttpModule, which would give you access to the IIS pipeline, including the final response. However, you would still need to initiate a request to IIS to actually kick off processing. Not sure if this would work for you.
From the MSDN documentation:
An HTTP module is an assembly that is
called on every request that is made
to your application. HTTP modules are
called as part of the request pipeline
and have access to life-cycle events
throughout the request. HTTP modules
therefore let you examine incoming
requests and take action based on the
request. They also let you examine the
outgoing response and modify it.
Gave you looked into the WebCkiebt class? You can make the request and get the response HTML.
http://msdn.microsoft.com/en-us/library/system.net.webclient.downloadstring(v=VS.100).aspx

IIS - Different processing of default document in Integrated Pipeline mode?

I have an HTTP Module to handle authentication from Facebook, which works fine in classic pipeline mode.
In integrated pipeline mode, however, I'm seeing an additional request pass through for the default document, which is causing the module to fail. We look at the request (from Facebook) to retrieve and validate the user accessing our app. The initial request authenticates fine, but then I see a second request, which lacks the posted form variables, and thus causes authentication to fail.
In integrated pipeline mode, an http request for "/" yields 2 AuthenticateRequests in a row:
A request where AppRelativeCurrentExecutionFilePath = "~/"
A request where AppRelativeCurrentExecutionFilePath = "~/default.aspx"
That second request loses all of the form values, so it fails to authenticate. In classic mode, that second request is the only one that happens, and it preserves the form values.
Any ideas what's going on here?
UPDATE: Here is an image of the trace from module notifications in IIS. Note that my module, FBAuth, is seeing AUTHENTICATE_REQUEST multiple times (I'd expect 2 - one for authenticate and one for postauthenticate, but I get 4).
I'm starting to believe this has something to do with module/filter configuration because I've found a (Vista) box running the same code that doesn't fire these events repeatedly - it behaves as expected. I'm working through trying to figure out what the difference could be...
Thanks!
Tom
My solution was to add the following code at the end of Application_BeginRequest:
if (Request.RawUrl.TrimEnd('/') == HostingEnvironment.ApplicationVirtualPath.TrimEnd('/'))
Server.Transfer(Request.RawUrl+"Default.aspx", true);
DefaultHttpHandler is not supported,
so applications relying on sub-classes
of DefaultHttpHandler will not be able
to serve requests If your application
uses DefaultHttpHandler or handlers
that derive from DefaultHttpHandler,
it will not function correctly. In
Integrated mode, handlers derived from
DefaultHttpHandler will not be able to
pass the request back to IIS for
processing, and instead serve the
requested resource as a static file.
Integrated mode allows ASP.NET modules
to run for all requests without
requiring the use of
DefaultHttpHandler. Workaround
Change your application to use
modules to perform request processing
for all requests, instead of using
wildcard mapping to map ASP.NET to all
requests and then using
DefaultHttpHandler derived handlers to
pass the request back to IIS.
Hmmm, or this could be the issue.
ASP.NET modules in early request
processing stages will see requests
that previously may have been rejected
by IIS prior to entering ASP.NET,
which includes modules running in
BeginRequest seeing anonymous requests
for resources that require
authentication ASP.NET modules can run
in any pipeline stages that are
available to native IIS modules.
Because of this, requests that
previously may have been rejected in
the authentication stage (such as
anonymous requests for resources that
require authentication) or other
stages prior to entering ASP.NET may
run ASP.NET modules. This behavior is
by design in order to enable ASP.NET
modules to extend IIS in all request
processing stages. Workaround
Change application code to avoid
any application-specific problems that
arise from seeing requests that may be
rejected later on during request
processing. This may involve changing
modules to subscribe to pipeline
events that are raised later during
request processing.
http://learn.iis.net/page.aspx/381/aspnet-20-breaking-changes-on-iis-70/

Resources