asp.net url minus pagename and querystring - asp.net

I've been looking around the web for a simple and straight forward solution for the following problem but I cant seem to find anything that suits my needs.
I have an asp.net site with many subdirectories as follows.
http://mysite.com/dir1/subdir1/
http://mysite.com/dir1/subdir2/
http://mysite.com/dir2/
http://mysite.com/dir3/subdir1/
etc...
On each of my sites pages I need to extract the URL to the page minus the pagename and querystring.
So if the page name was http://mysite.com/dir1/subdir2/mypage.aspx?param=5&param2=9
I would need the following http://mysite.com/dir1/subdir2/ I cant find any properties of the httprequest object that make this URL format readily available.

Take a look at this. It should give you everything you need, especially Url.Segments.

This works as well:
System.IO.Path.GetDirectoryName(url).Replace(#"\","/");

You're right, such thing is not ready so you need to make it yourself. One recipe is:
public string GetSubFolderURL()
{
string url = "http";
if (string.Equals(Request.ServerVariables["HTTPS"], "ON", StringComparison.CurrentCultureIgnoreCase))
url += "s";
url += "://";
url += Request.ServerVariables["SERVER_NAME"];
int port;
if (Int32.TryParse(Request.ServerVariables["SERVER_PORT"], out port) && port != 80)
url += ":" + port;
url += Request.ServerVariables["SCRIPT_NAME"];
return url.Substring(0, url.LastIndexOf("/") + 1);
}

Related

RouteCollection Querysting

I am trying to define MapPageRoute on the application global.asax but my problem is that I can not route the specific URL to a physical file with a query string.
For example I want to redirect http://mysite.com/Apple to http://mysite.com/product.aspx?id=95.
What I managed to achieve so far is if a user ask for ./Apple he will be redirected to ./product.aspx but I can not pass the query string.
Looking forward for your comments.
Try this:
if (Page.RouteData.Values["Apple"] != null)
{
int appleID = Convert.ToInt32(Page.RouteData.Values["Apple"]);
Response.Redirect("~/product.aspx?id=" + appleID.ToString(), true);
}

Asp.net 4 url rewrite a subdomain as a folder

What I'm trying to do is the following, I want to rewrite this kind of url:
blog.domain.com/...
into
domain.com/blog/...
It's in a shared host environment, using IIS7/ASP.Net 4. Another thing is that both the domain and the blog subdomain have different aps running. I've been searching for hours for what's the best solution here, and I hope someone can guide me a bit here. Thanks!
Here is an attempt as first idea.
// keep a valid list somewhere
List<string> cValidNames = new List<string>();
cValidNames.Add("blog");
// get the host
//string TheHost = Request.Url.Host;
string TheHost = "blog.domain.com";
// find the first part, assume that the domain is standard and not change
int WhereStarts = TheHost.IndexOf(".domain.com");
// if we found it
if(WhereStarts != -1)
{
string cTheFirstPart = TheHost.Substring(0, WhereStarts);
// if its on the valid domain (exclude the www)
if (cValidNames.Contains(cTheFirstPart))
{
// now I add in the frond the name and continue with the rest url
string cFinalPath = "/" + cTheFirstPart + Request.RawUrl;
// now rewrite it.
HttpContext.Current.RewritePath(cFinalPath, false);
return;
}
}

Is it safe to use Request.ApplicationPath for cookie path

Is it safe to use such code?
Response.Cookies[cookieName].Path = Request.ApplicationPath + "/";
I want to know about all corner cases, please...
In short, no, it's not safe. Using cookie paths is fraught with problems as they are case sensitive in IE and Chrome, but not FF. This means any mismatch in path case will stuff things up.
When generating a cookie, if the path you set differs in case from what the user typed, browsers won't store it.
When the user returns, if the path they enter differs in case from the first trip, the browser won't supply the cookie with the request.
What problem are you trying to solve?
If your application runs in the root of a domain, Request.ApplicationPath == "/". Hence, with your code, the path of your cookie will be //. You can dodge around this problem by doing this:
cookie.Path = Request.ApplicationPath;
if (cookie.Path.Length > 1) cookie.Path += '/';
As Will correctly points out, you will want to make sure that your application enforces a consistent casing of URLs (i.e. redirect all requests with URLs containing uppercase letters to their lowercase equivalent).
Other than that, I believe you should be fine doing this. If you want all of your cookies to be "application scoped", consider creating a custom IHttpModule with code like this (or extend global.asax.cs):
private void Application_EndRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
var cookiePath = app.Request.ApplicationPath;
if (cookiePath.Length > 1) cookiePath += '/';
foreach (string name in app.Response.Cookies.AllKeys)
{
var cookie = app.Response.Cookies[name];
cookie.Path = cookiePath;
}
}
No, it's not safe, for the reasons that Will specified.
But... You may want to employ this technique to fulfill your intent.

SEO: Duplicated URLs with and without dash "/" and ASP.NET MVC

after reading this article "Slash or not to slash" (link: http://googlewebmastercentral.blogspot.com/2010/04/to-slash-or-not-to-slash.html) on Google Webmaster Central Blog (the oficial one) I decided to test my ASP.NET MVC app.
For example:
http://domain.com/products and http://domain.com/products/ (with "/" in the end), return the code 200, which means: Google understands it as two different links and likely to be a "duplicated content". They suggest to choose the way you want... with or without dash and create a 301 permanent redirect to the preferred way.
So if I choose without dash, when I try to access http://domain.com/products/ it will return a 301 to the link without dash: http://domain.com/products.
The question is, how can I do that with ASP.NET MVC?
Thanks,
Gui
If your using IIS 7 you could use the URL Rewrite Extension ScottGu has a blog post about it here.
Alternatively if you want to do it in code you could inherit from PerRequestTask. Here some sample code the removes the www from an address - this is from Shrinkr:
public class RemoveWww : PerRequestTask
{
protected override TaskContinuation ExecuteCore(PerRequestExecutionContext executionContext)
{
const string Prefix = "http://www.";
Check.Argument.IsNotNull(executionContext, "executionContext");
HttpContextBase httpContext = executionContext.HttpContext;
string url = httpContext.Request.Url.ToString();
bool startsWith3W = url.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase);
bool shouldContinue = true;
if (startsWith3W)
{
string newUrl = "http://" + url.Substring(Prefix.Length);
HttpResponseBase response = httpContext.Response;
response.StatusCode = (int) HttpStatusCode.MovedPermanently;
response.Status = "301 Moved Permanently";
response.RedirectLocation = newUrl;
response.SuppressContent = true;
response.End();
shouldContinue = false;
}
return shouldContinue ? TaskContinuation.Continue : TaskContinuation.Break;
}
}
You would just need to check for the url ending with a / in your code.
** Note this does use a 3rd party dll - System.Web.MVC.Extensibility namespace. **
It dosnt matter really for Google, but what does matter is if both urls'
http://domain.com/products and http://domain.com/products/ show the same page, you also need to watch with windows servers that links to your site like from external pages where the user has typed http://domain.com/PRODUCTS/ will aloso be seen as a diffrent page as the web is case sensitive.
There is away round this with the use of canonical url meta tag, it tell s google what the page name is really, so will avoid duplicate pages which ant really diuplicate
http://googlewebmastercentral.blogspot.com/2009/02/specify-your-canonical.html
you need to check the URI in the INIT event and check the URI to see if it coming in with the slash, if it is, simply do a redirect and add the 301 header to the output response.

Find application root URL without using ~

I need to construct the URL of a page in a String, to send it an email (as part of an email verification system). If i use the ~ symbol to denote the app root, it is taken literally.
The app will be deployed on a server on three different sites (on different ports) and each site can be accessed via 2 different URLs (one for LAn and one for internet).
So hardcoding the URL is out of question. I want to construct the url to verify.aspx in my application
Please help
You need this:
HttpContext.Current.Request.ApplicationPath
It's equivalent to "~" in a URL.
http://msdn.microsoft.com/en-us/library/system.web.httprequest.applicationpath.aspx
Unfortunately none of the methods listed generated the full url starting from http://---.
So i had to extract these from request.url. Something like this
Uri url=HttpContext.Current.Request.Url;
StringBuilder urlString = new StringBuilder();
urlString.Append(url.Scheme);
urlString.Append("://");
urlString.Append(url.Authority);
urlString.Append("/MyDesiredPath");
Can someone spot any potential problems with this?
Try:
HttpRequest req = HttpContext.Current.Request;
string url = req.Url.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped)
+ ((req.ApplicationPath.Length > 1) ? req.ApplicationPath : "");
You need to put the URL as part of your web application's configuration. The web application does not know how it can be reached from the outside world.
E.g. consider a scenario where there's multiple proxies and load balancers in front of your web server... how would the web server know anything but its own IP?
So, you need to configure each instance of your web application by adding the base URL e.g. as an app setting in its web.config.
You can use HttpRequest.RawURL (docs here)property and base your URL on that, but if you are behind any kind of redirection, the RawURL may not reflect the actual URL of your application.
I ended up with this. I take the request url, and use the position of Request.ApplicationRoot to discover the left part of the uri. Should work with applications hosted in a virtual directory "/example" or in the root "/".
private string GetFullUrl(string relativeUrl)
{
if (string.IsNullOrWhiteSpace(relativeUrl))
throw new ArgumentNullException("relativeUrl");
if (!relativeUrl.StartsWith("/"))
throw new ArgumentException("url should start with /", "relativeUrl");
string current = Request.Url.ToString();
string applicationPath = Request.ApplicationPath;
int applicationPathIndex = current.IndexOf(applicationPath, 10, StringComparison.InvariantCultureIgnoreCase);
// should not be possible
if (applicationPathIndex == -1) throw new InvalidOperationException("Unable to derive root path");
string basePath = current.Substring(0, applicationPathIndex);
string fullRoot = string.Concat(
basePath,
(applicationPath == "/") ? string.Empty : applicationPath,
relativeUrl);
return fullRoot;
}
This has always worked for me:
string root = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, "");

Resources