My requirement is to redirect user to new url from old url . My entity is as follows:
public class HttpRedirect
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "Old url is required.")]
[MaxLength(1000)]
//[Url]
[Display(Name = "Old Url")]
public string OldUrl { get; set; }
[Required(ErrorMessage = "New url is required.")]
[MaxLength(1000)]
//[Url]
[Display (Name = "New Url")]
public string NewUrl { get; set; }
}
Url is commented so that I can work in localhost.
So when Old url is requested I want the request is transferred to new url To achieve this in global.asax file in Application_BeginRequest event I have following code
protected void Application_BeginRequest(object sender, EventArgs e)
{
//You don't want to redirect on posts, or images/css/js
bool isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get");
if (isGet && HttpContext.Current.Request.Url.AbsolutePath.Contains(".") == false)
{
string lowercaseURL = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
string newUrl = new HttpRedirectRepository().RedirectUrl(lowercaseURL);
if(newUrl != null)
{
lowercaseURL = newUrl;
}
lowercaseURL = lowercaseURL.ToLower().Trim() + HttpContext.Current.Request.Url.Query;
Response.Clear();
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", lowercaseURL);
Response.End();
}
}
I have implemented the above code to accomplish 2 task. 1. Change url to lower case 2. If new url is available for requested url redirect to that url.
With my above implementation I have strong feeling that its working but causing infinite loop by redirecting to a lowercaseURL
So how can I prevent multiple redirection. For e.g. I request http://localhost:80/mypage and I have set its new url to http://localhost:80/home then when mypage is requested it should redirect to home making url in lowercase and redirect should occur only one time.
note
- I need to redirect within my own domain only.
- User will enter full url address for both old and new url.
UPDATE
With some hint from @RobertHarvey I have modified my code as follows which is working for me
protected void Application_BeginRequest(object sender, EventArgs e)
{
//You don't want to redirect on posts, or images/css/js
bool isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get");
if (isGet && HttpContext.Current.Request.Url.AbsolutePath.Contains(".") == false)
{
bool redirect = false;
string requestUrl = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
//You don't want to change casing on query strings
string newUrl = new HttpRedirectRepository().RedirectUrl(requestUrl);
if (newUrl != null)
{
requestUrl = newUrl;
redirect = true;
}
if (Regex.IsMatch(requestUrl, @"[A-Z]"))
{
requestUrl = requestUrl.ToLower().Trim() + HttpContext.Current.Request.Url.Query;
redirect = true;
}
if (redirect)
{
Response.Clear();
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", requestUrl);
Response.End();
}
}
}
Though still I believe updated implementation has some limitation. I would appreciate any further code enhancement and case coverage.