Dynamic 'twitter style' urls with ASP.NET
- by Desiny
I am looking to produce an MVC site which has complete control of the url structure using routing.
The specific requirements are:
www.mysite.com/ = homepage (home controller)
www.mysite.com/common/about = content page (common controller)
www.mysite.com/common/contact = content page (common controller)
www.mysite.com/john = twitter style user page (dynamic controller)
www.mysite.com/sarah = twitter style user page (dynamic controller)
www.mysite.com/me = premium style user page (premium controller)
www.mysite.com/oldpage.html = 301 redirect to new page
www.mysite.com/oldpage.asp?id=3333 = 301 redirect to new page
My routes look as follows:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Common",
"common/{action}/{id}",
new { controller = "common", action = "Index", id = "" }
);
routes.MapRoute(
"Home",
"",
new { controller = "Home", action = "Index", id = "" }
);
routes.MapRoute(
"Dynamic",
"{id}",
new { controller = "dynamic", action = "Index", id = "" }
);
In order to handle the 301 rredirct, I have a database defining the old pages and their new page urls and a stored procdure to handle the lookup. The code (handler) looks like this:
public class AspxCatchHandler : IHttpHandler, IRequiresSessionState
{
#region IHttpHandler Members
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
if (context.Request.Url.AbsolutePath.Contains("aspx") && !context.Request.Url.AbsolutePath.ToLower().Contains("default.aspx"))
{
string strurl = context.Request.Url.PathAndQuery.ToString();
string chrAction = "";
string chrDest = "";
try
{
DataTable dtRedirect = SqlFactory.Execute(
ConfigurationManager.ConnectionStrings["emptum"].ConnectionString,
"spGetRedirectAction",
new SqlParameter[] {
new SqlParameter("@chrURL", strurl)
},
true);
chrAction = dtRedirect.Rows[0]["chrAction"].ToString();
chrDest = dtRedirect.Rows[0]["chrDest"].ToString();
chrDest = context.Request.Url.Host.ToString() + "/" + chrDest;
chrDest = "http://" + chrDest;
if (string.IsNullOrEmpty(strurl))
context.Response.Redirect("~/");
}
catch
{
chrDest = "/";// context.Request.Url.Host.ToString();
}
context.Response.Clear();
context.Response.Status = "301 Moved Permanently";
context.Response.AddHeader("Location", chrDest);
context.Response.End();
}
else
{
string originalPath = context.Request.Path;
HttpContext.Current.RewritePath("/", false);
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest(HttpContext.Current);
HttpContext.Current.RewritePath(originalPath, false);
}
}
#endregion
}
It is very simple to look up a user and in fact the above code does this. My problem is in the dynamic / premium part.
I am trying to do the following:
1) in the dynamic controller, lookup the username.
2) if the username is in the user list (database), show the Index ActionResult of the Dynamic controller.
3) if the username is not found, look up the username in the premium list
4) if the username is fund in the premium list (database) then show the Index ActionResult of the Preium controller.
5) If all else fails jump to the 404 page (which will ask the user to sign up)
Is this possible?
Looking up the user twice is a bad idea for performance?
How do I do this without redirecting?