asp.net global.asax Application_BeginRequest - c#

I have a site with multiple domains pointing to it. I wanted to redirect all requests to main domain so I've created a method called RedirectToRealDomain("domain.com") to check and redirect all requests to my preferred domain
At the moment it lives on Session_Start but I am planing to move it to Application_BeginRequest event.
Is that good idea? As I understand Session_Start only raised when new session started but Application_BeginRequest raised on all requests. RedirectToRealDomain method doesn't do any DB lookups or anything expensive apart from comparing strings.

Yes, that will work. I use an HTTP module's "BeginRequest" event to do the same thing on my site.
Another option is to create a 2nd IIS site and point all of the other domains to this site. Then you can use the IIS management console to redirect all requests to the 1st site.

This should be fine, but there are other non-programming ways of doing this from within IIS, which I presume would be less overhead and probably a more "correct" way of doing it. Your understanding of when the events are raised is correct, though and your solution should work and not be too much of a server drain.
See here for how to do it in IIS:
http://www.getfoundnow.com/iis_301_redirect.htm

Related

Making relative urls in asp.net webform custom classes without Request

I have some kind of a job scheduling implemented which calls a function ProcessJob. Now inside this method I need to generate url to one of my pages i.e DoanloadPage.aspx?some_params. That url is sent to user via email and when user clicks that link, it will take to the page.
The problem here is that I am not generating url in a web request method or I don't have access to the Request object. URL need to be generated in a custom class which is threaded i.e not in a web request.
So I can't go with these solutions:
HostingEnvironment.MapPath("test.aspx");
VirtualPathUtility.ToAbsolute("123.aspx");
HttpContext.Current.Request.Url.Authority;
None of these works because I think they all rely on current request or session somehow. So how do I generate urls for my app inside my code so I can use them anyway I want.
If your method cannot use HttpContext.Current.Request.Url, for example in case it's a background scheduled task, then you can use either of the following options:
In case that your code is hosted in the same ASP.NET application, you can pass the site domain name of the site to your class, in the first request. To do so, you need to handle Application_BeginRequest event and get the domain from HttpContext.Current.Request.Url and then pass it to your class, or store it in an application scope storage. You can find an implementation in this post or the original article.
Note: The code is available in SO, so I don't repeat the code
here.
If your code is not hosted in the same ASP.NET application or if for any reason you don't want to rely on Application_BeginRequest, as another option you can store the site domain name in a setting (like appsettigs in app.condig or web.config if it's web app) and use it in your code.
You can do something like this. Dns.GetHostName will return the name of the computer that is hosting the site. You can use that to check if the site is on a development server.
string domain = "www.productionurl/123.aspx";
if (Dns.GetHostName() == "Development")
{
domain = "www.developmenturl/123.aspx";
}
The Dns.GetHostName() is not the only way to check. You could also use the HostingEnvironment.ApplicationPhysicalPath. You can check that also and see if the path is that of the development server.
My answer is: don't do this. You're building a distributed system, albeit a simple one, and generally speaking it is problematic to introduce coupling between services in a distributed system. So even though it is possible to seed your domain using Application_BeginRequest, you are then tying the behavior of your batch job to your web site. With this arrangement you risk propagating errors and you make deployment of your system more complicated.
A better way to look at this problem is to realize that the core desire is to synchronize the binding of your production site with the URL that is used in your batch job. In many cases an entry in the app.config of your batch would be the best solution, there really isn't any need to introduce code unless you know that your URL will be changing frequently or you will need to scale to many different arbitrary URLs. If you have a need to support changing the URL programmatically, I recommend you look at setting up a distributed configuration system like Consul and read the current URLs from your deployment system for both the IIS binding and the app.config file for your batch. So even in this advanced scenario, there's no direct interaction between your batch and your web site.

How do you make a Ajax Post to a Handler.ashx safe and stop the handler being called directly

In a Website environment how do you make an ajax post to Handler.ashx secure and how do you stop people calling that handler.ashx directly and putting rubbish in and possibly breaking things server side?
With firefox and firebug you can pretty much hack the post quickly and easily.
I was thinking of these ideas.
In the handler check if you are logged in.
List item on the load of the site create a unique ID is saved as a cookie and
when the handler is called then that ID must exist in the Ajax and
the handler
List item the ajax call must come from a certain page
Do you have any other ideas?
Thanks
Short answer
Use authentication (Windows, Forms, etc) and validate your input.
Slightly longer answer
If your site is configured with an authentication provider, your handler will follow the same rules.
You should always validate any user input or web service input. Don't assume that your client is giving you pristine input. As you have mentioned, anyone with basic web development skills can spoof a POST. Keep that in mind when validating.

How to prevent navigation being blocked while downloading using an IHttpHandler?

I'm using an IHttpHandler to deal with my downloads. It streams out the file.
However, this handler needs to compare a token to one that is stored in the session. Therefore, it uses IRequiresSessionState.
The problem is now: as long as IRequiresSessionState is there, the user cannot keep on navigating the website, while a download is running.
Is there maybe a different approach than using a handler, which would solve my problem (I still need to be IIS6 compatible, but if there's a solution for IIS7 only, it would still be okay)?
Note that I cannot change the session check. I have to access the session.
There are so many things in .NET and IIS I have not discovered yet, maybe there is some functionality one could use.
Cannot you just redirect the request to another handler with the token in the URL so that it doesn't need to access the session any more?

WCF Session Management

I am new to WCF and trying to accomplish a few things in terms of session management:
I would like to get an event on the server when a new session is opened/created.
I would like the ability to either close all open sessions, or get a list of open sessions and close specific ones (on the server, of course).
How would I go about doing this? Google has been surprisingly unhelpful...
The answer is going to be a lot of "it depends". Some of the bindings are not session aware. Something like BasicHttpBinding for example doesn't do sessions on its own, but if you enable ASP.net compatability mode you can get ASP.net's session management to work. You will then be able to use Session_Start and Session_End in global.asax to do what you want when sessions are opening or closing.
You should look at the binding you're using and see if it has some kind of session support built in, because some of them do.
If you're doing authentication, you could also imitate a session management system by mapping requests to authenticated users and storing the session record in the database.
I will say that in any case I'm not sure what "closing" a session is going to get you. Unless you're also locking the user out somehow, the next request will just immediately start a new session if the previous one was ended. Maybe if you explain what goal you want to accomplish (and why) we can be of further help.
I agree with Tridus's answer on this. You can use Session with WCF services by enabling ASP.NET Compatibility Mode.
Check http://msdn.microsoft.com/en-us/library/aa702542.aspx for an initial reading. Keep in mind - Services are supposed to be stateless by principle.

Find out in Global.Asax - Application_Start if ASP.NET application running locally

HttpContext.Current.Request.IsLocal is not available in Global.Asax/Application_Start (Request is not available in the context).
How else could I safely determine if my ASP.NET MVC application is started locally or not?
This is to rewrite my web.config conditionally (depending on whether the application is deployed (remote) or in testing (local)).
Thank you!
The Application_Start event will be fired when IIS/cassini/whatever loads up your app (way before any HTTP requests have been made).
Reading your comments you want this to be a "one time operation" which really makes no sense. Your application is not so much "started locally" but it may be requested locally and/or remotely several times throughout its life cycle. With this in mind you need to check on each request as David commented.
Maybe, it would be better if you explained a little more what you are trying to achieve?
It might be more appropriate to check this in the BeginRequest method instead of the Application_Start because the first request might be local but later you could call the application on some other domain and it will no longer be local.

Categories