Constructing URLs in ASP.NET to avoid dead links - asp.net

I'm working on a moderately-sized ASP.NET webforms site. URLs for internal links etc. are generally set using syntax like this:
<asp:HyperLink runat="server" NavigateUrl="~/Some/Path/MyPage.aspx" Text="Blah" />
This makes me a little nervous since those links are just strings and I'm worried if I rename or move a page that I'll have trouble chasing down all the references.
Is there some ASP.NET-y way to determine the actual path at runtime? I'm envisioning something like this:
NavigateUrl="<%= GetUrl(typeof(MyPage)) %>"

You can define the method GetUrl according to the logic of your folder structure. Assuming that your namespace does correspond to your Folder Structure a basic definition would be as below
public string GetUrl(System.Type CurrentType)
{
List<string> PathInNamespace = CurrentType.FullName.Split('.').ToList<string>();
PathInNamespace.RemoveAt(0);
return "/" + string.Join("/", PathInNamespace.ToArray());
}

What you really want is a CMS like Umbraco, Sitecore, OpenText etc.
However, you could knock something up yourself with a database and a table with ID and Url columns. Then you could just do:
NavigateUrl="<%= GetUrl("AwesomeLink") %>"
It can go off to the database, look up the ID and fill out the link ready for you. It'd also allow you to change links around without recompile.
It's similar to your idea except that you still need to tell it what link you'd like at some point. It can't guess for you.

One non code solution is to creat custom error pages to link to other portions of your website or insert a search box in said error pages. It's quick, simple and also helps with SEO.

Related

Understanding a url that references a CSS file in a SharePoint master page

For SharePoint, this is the entry you could put into your master page to link to a CSS file.
<SharePoint:CssRegistration
name="<% $SPUrl:~sitecollection/_catalogs/masterpage/dir/file.css %>"
runat="server"
after="SharepointCssFile"/>
Could someone please break down the pieces of this url? I don't understand the following parts of it and how they work together:
<% - I do know this means less than
$SPUrl:~sitecollection/ - Is this some kind of variable? What's ~ for?
%> - I do know this means greater than
CssRegistration is just one of the many ways of referencing CSS files in
SharePoint.
lower than (<) and greater than (>) obvious, and ~ refers to the root of the current web application.
CssRegistration is particularly interesting because you can use After to make sure your CSS is loaded after another CSS such as core.css
The real relevant parameter is name, which in this tag can be used with SPURL, which in turn can be used with sitecollection or site, to refer to the current sitecollection root, or just the current site/web.
Note that SPURL is only available on SharePoint Server, not Foundation.
To support Foundation you can use ProjectProperty, which takes Url or SiteUrl.
So to wrap up, SPUrl is a token available in SharePoint that we can use to specify a resource from a specific location, relative to the current page, web, site and others.

asp.net mvc how to manage urls/links and routing centrally (c# + js)

I keep running into problems with URLs and routing.
Couldn't find an answer on SO.
I would like to manage all of my urls/links in a single place.
This is for my C# MVC code and the js/jquery ajax code.
These urls are scattered throughout my application.
Moving to a production server needs some fixes and I don't like the fact that I need to look for all of the occurrences in the application.
I don't mind fixing this once - but I would like to do it only once.
Any ideas how to manage all of these links/urls as a group will be very appreciated.
Be happy ad enjoy life, Julian
Consider using T4MVC
You could use Html.ActionLink or
Html.BuildUrlFromExpression(c => c.ControllerAction())
Depends, if you have application reading off certain urls and those urls changed once in a while. then you might want to consider putting all those urls into a database table/etc and retrieve them using specific key.
that way, when your url changed, all you need to do is to change the url on your database and all your application will still be running fine.
Urls should be managed in a single place: the RegisterRoutes static method in Global.asax. In absolutely every other part of your application you should use Html helpers when dealing/generating urls. This way you will never have problems because helpers take into account your routing system.
So instead of writing:
$('#foo').click(function() {
$('#result').load('/mycontroller/myaction');
return false;
});
you use an HTML helper to generate this foo:
<%: Html.Action("foo", "myaction", "mycontroller") %>
and then:
$('#foo').click(function() {
$('#result').load(this.href);
return false;
});
Never hardcode a single url in your application except of course in global.asax which is the only centralized place urls should be defined. So basically every time you find yourself writing something of the form /foo/bar in some other part than global.asax you are doing it wrong.

Seeking global variable to define root url

I have a habit of hardcoding URLs into my HTML:
...logon to your account.
During development when I want to target a specific web-app version I will global search/replace the 'www.mySite' with something like 'myDev.mySite'.
Since this practice has become habitual I can't clearly remember if there's a drop-dead good reason I don't use relative address or if i'm just that persistently dumb.
I would like to think that .net has something similar to the way we define connectionstrings that I could define a root URL as a global variable but so far haven't found the feature.
In ASP.NET MVC, use
<a href='<%=Url.Action("Login")%>'>login</a>
it will automatically generate the URL that works.
<base href> pretty much does exactly what you want.
http://www.w3schools.com/TAGS/tag_base.asp
Jan's answer is the best for ASP.NET MVC, since you can independently change how URLs map to views. A more general solution for any ASP.NET site is by using the tilde. For example,
Page.ResolveClientUrl("~/My/Path.aspx")
Will automatically resolve the ~ to the web application root. Or if you use ASP.NET controls,
<asp:HyperLink runat="server" NavigateUrl="~/My/Path.aspx" Text="Link Text"/>
This will create a hyperlink with the path automatically resolved to the site root.

Theme Image URL Rebasing asp.net

I am implementing themes to enable an existing website to be rebranded (logos, colors, images etc.) depending on the requesting URL. I understand how to do that and have got the skins working fine except for some exceptions related to the URLs of images.
Specifically I have a control property that it is not feasible to skin. Prior to implementing themes it looked like this:
<DisplayImageChecked Url="~/Images/BobIcon-Green.png" />
Obviously that will not work with themes. So after much trial and error and reading I am trying to implement it like this:
<DisplayImageChecked Url="~/AppThemes/<%= Page.Theme %>/Images/BobIcon-Green.png" />
However that does not work. The generated html looks like:
<img src="AppThemes/%3C%25=%20Page.Theme%20%25%3E/Images/BobIcon-Green.png"/>
Any pointers in the right direction would be appreciated.
David
Use the binding syntax inside a databound control (watch the single vs double quotes):
<DisplayImageChecked Url='<%# "~/AppThemes/" + Page.Theme + "/Images/BobIcon-Green.png" %>' />
Is there a reason that you can't just dump the images in the same folder as the theme? If you put an image say for example: "image.gif" into the theme folder, then you can simply refer to it directly in your skin.
ImageUrl="image.gif"
This will resolve just fine when you apply this skin on a control in your page. Also much easier than trying to do the dynamic URL thing.
You may also use "Images/BobIcon-Green.png" as Url. ASP will take care of resolving the Url to the directory within your theme.
Here's the right way to go about your task:
Adorn your property with the UrlProperty attribute, this will tell ASP.NET to automatically translate your partial URL into the proper url.
Using "~/AppThemes/" + Page.Theme + "/Images/BobIcon-Green.png" will do the trick, but it's NOT the preferred way because you need to do all the work yourself and it's always good practice to leave all the work to ASP

How do I determine if an asp.net url has been "rewritten"?

I'm using http://urlrewriter.net/ to rewrite urls at my website. For example, I'm rewriting:
http://www.example.com/schedule.aspx?state=ca
to
http://www.example.com/california.aspx
What I'm trying to do (for SEO purposes) to to dynamically add the meta tag:
<meta name="robots" content="noindex,follow" />
only to the page that hasn't been rewritten. This is because I want both URLs to work, but only the rewritten one to be indexed by search engines.
How do I determine which version of the page has been requested?
EDIT
Answers below suggest a 301 redirect instead of using a meta tag. Maybe I'll do this, but I still want to know the answer to the underlying question... how do I know if the page has been rewritten?
personally, I would 301 redirect from the un-rewritten one to the re-written one, and only use the single copy of the page. It is easier for users, and from an SEO perspective, you have 1 copy of the content.
If you need to do this you can probably do something like:
<add header="X-WasRewritten" value="true" />
And you can check for the header in your view and add the robots meta tag if you need it.
This will get returned to the client too, so if you want to hide that you can write a CustomAction (http://urlrewriter.net/index.php/support/reference/actions/custom-action) which will set some kind of state value in your request.
However, having two URIs for the same resource is something I would not recommend. I suggest you just keep the one representation. If you're worried about invalidating old bookmarks you can set the old one to redirect to the new one.
Further to chakrit's answer, it looks like UrlRewriter.NET stores the original URL in the HttpContext, in a key called UrlRewriter.NET.RawUrl. So, you could try something like:
bool isPageRewritten =
!string.IsNullOrEmpty(HttpContext.Current.Items["UrlRewriter.NET.RawUrl"]);
Most obvious method is to use the Request.Url object in your page to get information about the URL and query string. For example:
if (Path.GetFileName(Request.Url.FilePath) == "schedule.aspx")
//Not rewritten
else
//rewritten
I think that's the job of HttpContext.Current.Items.
You can save the "Redirection" in HttpContext.Current.Items and then in your pages, you can check it for a certain added value.
I believe you can add hooks to urlrewriter.net that could do it, something alongs:
HttpContext.Current.Items["Redirected_From"] = currentUrlHere;
And then in your webpages, you could check it by:
if (!string.IsNullOrEmpty(HttpContext.Current.Items["Redirected_From"]))
// the page's been redirected, do something!
else
// no it's visited normally.
I have long since left it for the ASP.NET Routing framework in .NET 3.5 SP1, it is better than urlrewriter.net IMO.

Resources