Reputation: 1324
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
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.
Upvotes: 0
Views: 1040
Reputation: 239440
Your two "notes" are contradictory. If you only want to allow redirection within your domain, then recording a full URL, including a domain, is entirely unnecessary, and only serves to complicate things. Make the old/new URLs just absolute paths. This also solves your problem with working in development vs. production, since you don't need to worry about the data having the right domain for the right environment.
Note: your infinite redirect is a bug in your code here. You should be redirecting to newUrl
, not lowercaseUrl
. In the case where newUrl
is null, there is no redirect, so you should simply not redirect at all in that case.
Upvotes: 0