I have a simple folder structure for my multilingual website on localhost
Default.aspx
images
css
js
en/Default.aspx
en/ContactUs.aspx
....
ar/Default.aspx
ar/xxxxx.aspx
Problem i am facing is very strange to me. i have a simple code to check the browser language set by user and accordingly i redirect user to English or Arabic version of website.
Irrecpective of what code i wring it always redirects me to English version of website and executes the en/Default.aspx page
Even commenting all the code in Default.aspx page it still redirect it to the en/Default.aspx page. while it should not do any thing.
I have set Default.aspx as Set As Default Page but it doesn't make any difference. I removed even global.asa that had routing code, i also removed all the compiler code related to this website on local host but it still keeps doing the same thing.
I have checked web.config file there is nothing wrong with that.
Even after removing the Default.aspx page it sill redirects me to en/Default.aspx i am frustrated with this problem.
I am not sure what is wrong. I re-started system with no result.
I am using visual studio 2010 for asp.net web form project.
http://localhost:49831/AlShindagah/
ALWAYS take me to below URL
http://localhost:49831/AlShindagah/en/Default.aspx
CODE of Default.aspx before i deleted it
public partial class DefaultMain : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//switch (Session["lang"].ToString().ToLower())
//{
// case "en-us":
// Response.RedirectPermanent("~/en/Default.aspx");
// break;
// case "ar-ae":
// Response.RedirectPermanent("~/ar/Default.aspx");
// break;
// default:
// Response.RedirectPermanent("~/en/Default.aspx");
// break;
//}
}
//// Localization and Globalization code
//protected override void InitializeCulture()
//{
// String lang = Request["Language"];
// Session["lang"] = Helper.DetectLanguage(lang);
// //Set Direction of page LTR/RTL
// if (Session["lang"] == "ar-AE")
// {
// Session["PageDIR"] = "rtl";
// }
// else
// {
// Session["PageDIR"] = "ltr";
// }
// base.InitializeCulture();
//}
}
You had previously used Response.RedirectPermanent("~/en/Default.aspx");. A complying browser would remember this and always redirect you there.
Clear your browser cache and try again :)
As a side note, use Redirect instead of RedirectPermanent. If I'm accessing www.mysite.com from a browser and www.mysite.com RedirectPermanent's me to www.myothersite.com, a complying browser would remember this and for all future requests to www.mysite.com, it would call www.myothersite.com.
Related
First of all, we are using MVC 3, ASP.NET 4.0 and Visual Studio 2010.
Our goal is to open up our brand new web site to an open beta. We want to redirect a slowly increasing percentage of our traffic to our new site while the rest of our traffic goes to our existing site...
We were hoping to do this via a load balancer, but this is no longer an option due to resources, infrastructure and time. Right now it seems our only option is to do it via software.
Has anyone here done this? Do you have a good strategy or solution?
We will have two different URLS and we can use cookies to achieve this if needed.
It's fairly simple and would be done the same way user's are redirected to mobile site.
Implement Application_PreRequestHandlerExecute in global.asax.cs
If they fit whatever criteria you decide, Response.Redirect them. I'd store a cookie on whomever is going to stay on one site or the next so they dont erroneously get redirected while in the middle of viewing the non-beta site. This also doesn't handle the case of people not using cookies.
This is pseudo code, so it may not be 100% correct
protected void Application_PreRequestHandlerExecute(object sender, EventArgs
e)
{
if(Request.Cookies["BetaResult"] == null)
{
var cookie = new HttpCookie("BetaResult");
cookie.Expires = DateTime.Now.AddDays(1d);
if(whatever logic to redirect to beta)
{
cookie["BetaResult"] = "Beta";
Response.Cookies.Add(cookie);
Response.Redirect("your beta site");
}
else
{
cookie["BetaResult"] = "Main";
Response.Cookies.Add(cookie);
}
}
else
{
//if cookie value is beta, redirect to beta site, they 'are a chosen one'
}
}
how can I deny direct access (by typing the full url) to pages in asp.net, without using roles in web.config something simle.
I've used :
if (Session.IsNewSession)
Response.Redirect("Default.aspx");
the problem with it is in the first time everything is ok and the redirect is working, but if I open a new tab in the same browser and enter the url again it fails.
How can it be solved?
thanx
Try this:
Page 1
Context.Items.Add("somevar","someval");
Page 2
if ( Context.Items["somevar"] == null )
{
// the page is not redirected from Page 1
}
Using session you can solve this issue.
Build an HttpModule and in context_BeginRequest you can get the current URL . Later conditionally redirect to the default page.
public class RedirectionModule : IHttpModule
{
void context_BeginRequest(object sender, EventArgs e)
{
//this user already already eligible to go inside page ?
if (Session["eligible-to-go-inside"] == null)
{
//new user
//check current request url is default.aspx
//if not forward to default page
}
}
}
in default.aspx page if the user full fill the requirement to go to inner page (like logged in) then set
Session["eligible-to-go-inside"] = "yes";
Issues that I am facing and my questions are as follows:-
I am running this code on localhost only, is there any free service or something where I can run this sample webite of mine online?
Else the IP address the follwoing code returns is always 127.0.0.1. How do I test my code? Currently I gave static values for IP address.
HTTP_X_FORWARDED_FOR is always returning null value. I have read that only HTTP_X_FORWARDED_FOR contains the real IP address of a user.
Does REMOTE_ADDR contain real IP address of a user or the IP in it can also be spoofed? I just want to know the country in which the user is sitting in so I can redirect the user based on the ISO codes.
One major issue that I am facing is that I am unable to see MasterPageFile property in this Global.asax file.
What I want is something like this :-
If the ISO code is "FR" then the master to be loaded for the site is FranceMaster.master
Else if ISO Code is "GB" then BritainMaster.master file is to be used.
In what part of this file do I set the master pages??
So basically I wanna learn how to Redirect a user based on the ISO code AND set the master page too. I gave hard coded IP address something like 122.87.234.1 then it gave me this error that Couldnt redirect properly. I googled about it and found out that the response.redirect
request was being called indefinately. If the following way is not how u redirect a user, how else one does it??
I am sure this kind of stuff has been implemented way too many times. Could someone PLEASE help me out with this one?? I would be grateful. Thanks.
below is the code I have written in Global.asax file :-
<%# Application Language="C#" %>
<%# Import Namespace="System" %>
<%# Import Namespace="System.Net" %>
<%# Import Namespace="System.Web.UI" %>
<%# Import Namespace="WorldDomination.Net" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
}
void Application_End(object sender, EventArgs e)
{
// Code that runs on application shutdown
}
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
}
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
}
void Session_End(object sender, EventArgs e)
{
// Code that runs when a session ends.
// Note: The Session_End event is raised only when the sessionstate mode
// is set to InProc in the Web.config file. If session mode is set to StateServer
// or SQLServer, the event is not raised.
}
void Application_BeginRequest(object sender, EventArgs e)
{
string ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ip))
{
string[] ipRange = ip.Split(',');
int le = ipRange.Length - 1;
string trueIP = ipRange[le];
ip = trueIP;
}
else
{
ip = Request.ServerVariables["REMOTE_ADDR"];
}
// string userHostIpAddress = "203.1.2.3";
string userHostIpAddress = ip;
IPAddress ipAddress;
if (IPAddress.TryParse(userHostIpAddress, out ipAddress))
{
string country = ipAddress.Country(); // return value: UNITED STATES
string iso3166TwoLetterCode = ipAddress.Iso3166TwoLetterCode(); // return value: US
}
if (ipAddress.Iso3166TwoLetterCode() != null)
{
if (ipAddress.Iso3166TwoLetterCode().ToLower() == "fr")
{
Response.Redirect("www.mysite.fr");
}
if (ipAddress.Iso3166TwoLetterCode().ToLower() == "ja")
{
Response.Redirect("www.mysite.com/BlockedAccess.aspx");
}
}
else
{
Response.Redirect("www.mysite.com");
}
}
</script>
EDIT:-
#Chris :: Thanks. I am a bit confused. If the IP address can always be spoofed, how can I ever get the country of a user? I mean how to make sure the user location that I am fetching is correct? Also, there are like 100s of pages on the actual application project that I have to work on. Presently I was just trying it out by making a sample application with just one page. Now, it would be quite a task to set that masterpagefile property in ALL the pages. Is there no way to get it done in a single place?? There are literally hundereds of pages in that web application. Please reply. Thanks.
For the redirect error use Server.Transfer instead of Response.Redirect. The latter will actually initiate a new request and cause the Application_BeginRequest code to fire again, launching your user into an infinite loop.
Regarding your other questions:
Regarding hosting, I would just do a search for "free asp.net hosting", or if you're willing to pay a few bucks for better service find a web host.
HTTP_X_FORWARDED_FOR will populate when the request is forwarded via a proxy server. Since you're testing locally and never pass through a proxy server this variable will never be populated. I also noticed that your code is grabbing the last value from HTTP_X_FORWARDED_FOR instead of the first. I believe that will give you the IP address of the last proxy the user passed through and not the actual client IP (maybe someone else can confirm this).
The user's IP address can always be spoofed.
If you want to dynamically switch your masterpage you will need to do this on the Page_Init event of every page. The best solution would likely be to set a session variable with the appropriate masterpage in your global.asax and then assign that as your masterpage in the Page_Init.
Global.asax:
if (ipAddress.Iso3166TwoLetterCode().ToLower() == "fr")
{
Session["MasterPage"] = "~/FrenchMaster.master";
Server.Transfer("www.mysite.fr");
On each page's Page_Init:
this.MasterPageFile = Session["MasterPage"].ToString();
If you're going to go down this route I would suggest creating a custom page class that implements this and that all of your pages in turn inherit from so you don't actually have to copy/paste this code to each page.
aware that there are a lot of questions relating to Forms Authentication and the persistence of cookies, but having spent most of a day delving around, I'm still having difficulties.
My Problem
I am working on a web app (VS2010 but webapp is f/w 3.5) which restricts access to certain parts of the app to authenticated users (whereas other parts are open). My problem is that my authentication cookies do not appear to be persisting after I close the browser.
My Approach
I have written a simple login.aspx page which is configured in web.config as follows:
<authentication mode="Forms">
...and the individual pages' behaviour are declared like so:
<location path="ClientManageAccount.aspx">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
...which works fine in every respect EXCEPT for these cookie shenanigans...
I create the authentication cookie manually once I have authenticated my user's login & password against the database (which works fine) in the login.aspx page. If the user selects the 'keep me logged in' checkbox, the cookie is generated using this method:
private void GenerateAuthenticationCookie(int expiryInMinutes, Guid userGuid)
{
DateTime cookieExpiration = DateTime.Now.AddMinutes(expiryInMinutes); // change to months for production
var authenticationTicket =
new FormsAuthenticationTicket(
2,
userGuid.ToString(),
DateTime.Now,
cookieExpiration,
true,
string.Empty,
FormsAuthentication.FormsCookiePath);
// ticket must be encrypted
string encryptedTicket = FormsAuthentication.Encrypt(authenticationTicket);
// create cookie to contain encrypted auth ticket
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
authCookie.Expires = authenticationTicket.Expiration;
authCookie.Path = FormsAuthentication.FormsCookiePath;
// clear out existing cookie for good measure (probably overkill) then add
HttpContext.Current.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
HttpContext.Current.Response.Cookies.Add(authCookie);
}
The objective here is that I store a user Guid in the auth cookie, which I will then use to restore a user object into session (this is also in the login.aspx page, and my thinking is that I'd like to pluck the user guid from the auth cookie that I have created, and use it to stuff the corresponding user record into session and redirect to the requested page):
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TryAutoLogin();
}
}
private void TryAutoLogin()
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(FormsAuthentication.FormsCookieName);
if (cookie != null)
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket != null)
{
if (ticket.Name.Length > 0)
{
try
{
Guid userGuid = new Guid(ticket.Name);
KUser user = UserFunctions.GetUserFromUserGuid(userGuid);
if (user != null) Session["User"] = user;
FormsAuthentication.RedirectFromLoginPage(userGuid.ToString(), true);
}
catch (Exception anyException)
{
// don't do anything for now - do something smart later :-) }
}
}
}
}
Finally, here is the code for the login button on my login.aspx page:
protected void Submit_OnClick(object sender, EventArgs e)
{
long userId = 0;
UserAuthenticationStatus status;
status = (UserAuthenticationStatus)UserFunctions.UserAuthenticates(EmailAddress.Text, Password.Text, ref userId);
switch (status)
{
case UserAuthenticationStatus.Authenticated:
//email address and password match, account ok, so log this user in
KUser user = UserFunctions.GetUser(userId);
Session["User"] = user;
if (ChkRememberMe.Checked)
{
GenerateAuthenticationCookie(15, user.UserGuid); // 15 minutes
FormsAuthentication.RedirectFromLoginPage(user.UserGuid.ToString(), true);
}
else
{
FormsAuthentication.RedirectFromLoginPage(user.UserGuid.ToString(), false);
}
break;
case UserAuthenticationStatus.AuthButLocked:
// email/pwd match but account is locked so do something
ShowLockedAccountMessage();
break;
case UserAuthenticationStatus.EmailFoundIncorrectPassword:
case UserAuthenticationStatus.EmailNotFound:
case UserAuthenticationStatus.Unknown:
// either the email wasn't found, or the password was incorrect or there was some other problem
// present message stating this and offer chance to register
ShowFailedLoginMessage();
break;
default:
ShowUnavailableMessage();
break;
}
}
As you can see, there's nothing particularly complex going on, but despite the fact that the authCookie which is created in GenerateAuthenticationCookie(..) being created correctly (as far as I can tell) it does not persist.
One thing I have noticed is that if I place some code into the Application_AuthenticateRequest method in global.asax.cs, such as:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(FormsAuthentication.FormsCookieName);
if (cookie != null)
{
int x = 4; // just a dummy line so that I can set a breakpoint
}
}
...that breakpoint is sometimes hit following a new browser session, although it stops being hit once I navigate away from the startup page (in this case a dummy start.aspx page used purely for dev & testing).
So, apologies for the long question, but I'm truly suffering here.
Things I have checked/tried
Ensuring that the code is being executed - YES
Browser settings - i.e. no deletion of cookies on exit - CONFIRMED NO DELETION
Trying different timeouts - e.g. equal or different to the web.config timeout, doesn't seem to matter...
...and of course at least twenty or thirty different previous questions, but to no avail.
System/Dev Environment
Windows 7 64-bit, VS2010 (but proj is a 3.5), SQL Server 2008 Express.
On my dev server, this problem remains so I'm not sure it's necessarily environmental - that machine is a WS2008R2 box running SQL 2008R2 - and the same problem remains.
Does anyone, anywhere, have any ideas for things I can try here? I have a hunch I could get this working by intercepting the initial Application_AuthenticateRequest hit in global.asax.cs and stuffing something into session state to mark as 'authenticated' (to avoid an expensive authentication attempt every time that method is called, which turns out to be several times per page.
Thanks in advance,
John
OK, having spent all that time writing that, I had a moment of clarity and realised that (a) I didn't need to be doing any of that checking on the Page_Load() as (if this were working properly) the login.aspx page wouldn't be called at all, and (b) I ought to have been able to get to the cookie from the Session_Start - which is where I relocated the TryAutoLogin code.
This in itself was a step forward, but despite retrieving the cookie and therefore the user guid from it, I found that by I was still getting punted back to the login.aspx page.
It was at this point I recalled the fact that I have a parent master page and two child master pages - one which I set for non-authentication pages (e.g. homepage) and one for those pages requiring authentication. I vaguely recalled a problem with session timeouts and had placed the following code in the OnInit override:
if (Session["User"] == null)
{
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
Response.End();
}
...which in itself wasn't so bad (and avoided a nasty bug on timeouts) but also on the start.aspx page, I found this gem:
Session.Clear();
...in the Page_Load!
So, what was happening was that I was inadvertently clearing the session into which I had placed my newly recovered user record. Which meant that the authorisation master page's OnInit override was then detecting the absence of the user object and - ta dah! - signing the user out, which in turn removes the authorisation cookie...
So, a bit of wiring and some sleuthing later, and I can put this one to bed.
Thanks for reading (even if I did figure it out on my own)... :)
I would like to execute a frame redirect in C# from my managed module for the IIS 7.
When I call context.Response.Redirect(#"http://www.myRedirect.org");the correct page is shown but also the address is shown in the browser. And that is exactly what I do not want.
So I want something like:
private void OnBeginRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
// make a frame redirect if a specified page is called
if (context.Request.ServerVariable["HTTP_REFERER"].Equals(#"http://www.myPage.org/1.html"))
{
// perform the frame redirect here, but how?
// so something like
context.Response.Redirect(#"http://www.myRedirect.org");
// but as I said that doesn't redirect as I want it to be
}
}
Any ideas about that?
EDIT:
I tried the example, so I have:
private void OnBeginRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
// make a frame redirect if a specified page is called
if (context.Request.ServerVariable["HTTP_REFERER"].Equals(#"http://www.myPage.org/1.html"))
{
// perform the frame redirect here, but how?
context.Response.Write(#"<html>");
context.Response.Write(#"<head>");
context.Response.Write(#"</head>");
context.Response.Write(#"<frameset rows=""100%,*"" framespacing=""0"" frameborder=""NO"" border=""0"">");
context.Response.Write(#"<frame src=""http://www.myRedirect.org"" scrolling=""auto"">");
context.Response.Write(#"</frameset>");
context.Response.Write(#"<noframes>");
context.Response.Write(#"<body>Some text...");
context.Response.Write(#"</body>");
context.Response.Write(#"</noframes>");
context.Response.Write(#"</html>");
}
}
But that also doesn't correctly redirect. I still have the redirect address shown in my browser. So any other idea?
EDIT:
I obviously made a mistake. The code above works and does what I want. It first didn't work because my redirect url was doing something unexpected.
To perform a frame redirect you need to send back the HTML code containing a frameset with a single frame, with it's source set to http://www.myRedirect.org. As far as the server and browser is concerned no redirect has happened - it's just received some HTML code.
Performing a Response.Redirect will, as you've observed, cause the browser to make a fresh new request to the new page, showing the user the new address in the title bar. It's typically used for when a page actually changes its address, but the owners still want it reachable from the original URL as well.
EDIT: HTML frame redirect sample: http://en.wikipedia.org/wiki/URL_redirection#Frame_redirects