Scott Hanselman

Introducing ASP.NET FriendlyUrls - cleaner URLs, easier Routing, and Mobile Views for ASP.NET Web Forms

September 09, 2012 Comment on this post [91] Posted in ASP.NET | Javascript | Mobile | Open Source | VS2012
Sponsored By

I've said before how surprised I am that more ASP.NET Web Forms developers don't use Routing to make their URLs prettier. If you don't want "foo.aspx" in your URL, then change it with Routes.MapPageRoute(). However, managing Routing Tables is a little tedious and most WebForms folks aren't used to the concept and don't want to invest the time.

I've also heard a number of ASP.NET Web Forms Developers express a little envy at how easy it is to make a site that has both desktop and mobile views using ASP.NET MVC. They like the idea of seeing an iPhone show up and showing a different  view while reusing logic as I've shown in my mobile talks before.

Let's solve both these problems with a new ASP.NET feature just pre-released today in alpha form on NuGet. My peer Damian Edwards and developer Levi Broderick along with QA by  Pranav and Anton have come up with a pretty awesome solution based on the original "Smarty Routes" idea from Eilon Lipton and the result is FriendlyUrls.

Install-Package Microsoft.AspNet.FriendlyUrls -pre

NOTE: If you've been paying attention to ASP.NET for the last few months you'll recognize this incremental useful but appropriately sized forward motion as being all part of the One ASP.NET master plan.

It's also worth noting that this FriendlyUrls NuGet package includes BOTH an ASP.NET 4.5 and ASP.NET 4 version so .NET 4 folks get love too.

FriendlyUrls Hello World Example

First, the obvious example. Bring up Visual Studio and File | New Project | New ASP.NET Web Forms Application. Now, from the Package Manager Console or from Manage NuGet Packages, install Microsoft.AspNet.FriendlyUrls. You'll need to "Include Prerelease" packages with -pre from the command line or via the dropdown in the UI.

Microsoft.AspNet.FriendlyUrls -pre shown in the UI

Be sure to read the readme.txt that pops up as you'll need to ensure that the FriendlyUrls routing gets called on application startup! I added this one line to my Application_Start:

RouteConfig.RegisterRoutes(RouteTable.Routes);

Here's the cool part. If I hit one of my existing links, like Contact.aspx, look what happened. See how the GET request for /Contact.aspx turned into a 301 redirect to /Contact?

/Contact.aspx turned into a 301 redirect to /Contact

If you have a Web Form called /Foo.aspx, you automatically get a /Foo route and can call your page like that! Hence, Microsoft.AspNet.FriendlyUrls.

Just by adding the one package and calling

routes.EnableFriendlyUrls();

in RouteConfig (this default came down with the NuGet package) my whole WebForms app loses its .ASPX extensions and gets reasonable defaults.

FriendlyUrls Advanced Sample

Get it? Ok, let's dig into some of the obvious next questions and some more advanced scenarios. How do I get values out of the URL? I'm used to Request.QueryString and Request.Form, but how do I get ahold of these URL segments?

Here's a Foo.aspx that I've visited via /Foo.

A basic Foo WebForms page

If I click "Click Me" the URL points to /Foo/bar/34.

Visiting /Foo/bar/34

NOTE: Be aware of the magic. It makes sense. If there was a 34.aspx in a folder called Bar in a folder called Foo, we would have used that file. There wasn't. If there was a file called Bar.aspx in a folder called Foo we would have used that. There wasn't. So, we used Foo.aspx and passed in the rest of the URL.

I can get the segments out like this:

<% foreach (var segment in Request.GetFriendlyUrlSegments()) { %>
<li><%: segment %></li>
<% } %>

UPDATE: One thing I forgot to mention was how to get the values out of the FriendlyURL. You can use things like [Form] and [QueryString] to model bind in WebForms. Now you can add [FriendlyUrlSegments] to get data out, like the ID in this example:

public SomeItem SomeItem_GetItem([FriendlyUrlSegments]int? id)
{
SomeItem item = db.SomeItem.Find(id);
return item;
}

They're sitting on the Request option. I did have to import the Microsoft.AspNet.FriendlyUrls namespace to have this extension appear.

<%@ Import Namespace="Microsoft.AspNet.FriendlyUrls" %>

Better yet, I can generate Friendly URLs without string concatenation!

<a href="<%: FriendlyUrl.Href("~/Foo", "bar", 34) %>">Click me</a>

Nice, eh? OK, let's make it mobile.

Mobile Routes with ASP.NET FriendlyUrls

When you bring down the NuGet package you'll also get a Site.Mobile.Master. If I visit them with the Electric Plum Mobile Simulator (iPhone) I see a default mobile page, automatically.

The Default Mobile Web Forms page in an iPhone

Ah, you see where this is going. I'll copy Foo.aspx to Foo.Mobile.aspx. I'll make a small change. I'll visit /Foo/bar/34 again except now I get the mobile master and the mobile foo, automatically.

image

What I want to support switching back and forth from Desktop to Mobile? Just add a ViewSwitcher control, also included.

<friendlyUrls:ViewSwitcher runat="server" />

Now I re-render and I get a "switch to mobile" and switch to desktop.

image

Now I can go back and forth between views and request a desktop site even when on mobile.

image

So basic mobile is nice but I might want very specific mobile views for iPhone, iPad, Opera Mobile, etc.

Super Advanced Mobile Routes for Specific Devices with ASP.NET FriendlyUrls

By default FriendlyUrls uses a class called WebFormsFriendlyUrlResolver but you can derive from this class and change its behavior however you like. Here's an example of a "DeviceSpecificWebFormsFriendlyUrlResolver" or, better yet, Mobile Friendly Urls for WebForms.

This derived URL resolver does just that, it resolves URLs to physical Web Forms pages. You'd then pass it into the overload of EnableFriendlyUrls(...);

IMPORTANT NOTE: This code is just a very early sample, there will be a more complete one released later.

public class DeviceSpecificWebFormsFriendlyUrlResolver : WebFormsFriendlyUrlResolver
{
private readonly IDictionary<string, string> _deviceUserAgentMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "Opera Mobi", "OperaMobile" },
{ "iPhone", "iPhone" },
{ "iPad", "iPad" }
};

protected override IList<string> GetExtensions(HttpContextBase httpContext)
{
var extensions = base.GetExtensions(httpContext).ToList();
if (extensions.Contains(MobileAspxExtension, StringComparer.OrdinalIgnoreCase))
{
// Base has determined we should look for a mobile page, let's add device specific
// extension to the beginning.
var deviceSpecificSufffix = GetDeviceSpecificSuffix(httpContext);
if (!String.IsNullOrEmpty(deviceSpecificSufffix))
{
extensions.Insert(0, "." + deviceSpecificSufffix + AspxExtension);
}
}
return extensions;
}

protected override bool IsMobileExtension(HttpContextBase httpContext, string extension)
{
return base.IsMobileExtension(httpContext, extension) ||
_deviceUserAgentMap.Values.Any(v => extension.Contains(v, StringComparison.OrdinalIgnoreCase));
}

protected override bool TrySetMobileMasterPage(HttpContextBase httpContext, Page page, string mobileSuffix)
{
var deviceSpecificSufffix = GetDeviceSpecificSuffix(httpContext);
if (!String.IsNullOrEmpty(deviceSpecificSufffix) && base.TrySetMobileMasterPage(httpContext, page, deviceSpecificSufffix))
{
// We were able to set a device specific master page, so just return
return true;
}

// Just use the base logic
return base.TrySetMobileMasterPage(httpContext, page, mobileSuffix);
}

private string GetDeviceSpecificSuffix(HttpContextBase httpContext)
{
foreach (var item in _deviceUserAgentMap)
{
if (httpContext.Request.UserAgent.Contains(item.Key, StringComparison.OrdinalIgnoreCase))
{
return item.Value;
}
}

return String.Empty;
}
}

Now we've created a map of device specific suffixes, so we can have not Foo.Mobile.aspx, but rather Foo.iPhone.aspx and Foo.OperaMobile.aspx, etc.

Here's a little demo that loads a bunch of names into a list. Here's /async, the desktop view.

A list of names on the desktop

Now we'll add jQuery mobile to the mobile master page, and use it on the mobile version of the same page. We're still calling the same data source and reusing all that code.

The list of names now as a jQuery mobile page inside an iPhone

I'm pretty jazzed about what this means for ASP.NET and Web Forms developers. We're going to continue to push forward and improve ASP.NET even now, after Visual Studio 2012 has been released. Sometimes we'll add small features via NuGet packages, sometimes editor improvements as free VSIX Extensions like the Web Essentials playground for 2012 and larger changes via released updates to all of ASP.NET.  I hope you like the direction we're heading.

Go play with Microsoft.AspNet.FriendlyUrls now and thank Damian and friends on Twitter!


This week's sponsor: Be part of GENERATION APP. Your Idea. Your App. 30 Days. Begin your 30-day journey to create a Windows Store style app and talk 1-on-1 with a Windows 8 app development pro. Get started today.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
September 09, 2012 10:41
Wow thats super cool :) Much awaited feature :) Thanks a lot for keeping a compatibility with 4.0. It will be really helpful for us. Thanks to Damian and Pranav! Definitely needed the feature in ASP.NET Webforms. Guys, you seriously rock \m/
September 09, 2012 11:28
Much relief and highly awaited. Had to do so much till now to acheive url rewriting HTTPmodule, web.config, urlrewrite.xml, .......

Looking forward to it. Thank you
September 09, 2012 11:52
Great addition to the ASP.NET WebForms Stack.

Can the QueryString Value provider still be used herewith or must one make use of the Request object as indicated in the sample?
September 09, 2012 11:52
Jacques - You can still have things in the QueryString like /foo?something=somevalue
September 09, 2012 14:37
This is all great,awesome really.
It may be helpful to see (or try) the implications of the magic behind physical files vs parameters, but I bet most applications have these sorts of magic hanging non-measured (and not having notable performance cost) anyway.

However, this was generally fine with the routes support that already exists now. sure it's easier and it's hence welcome and everything, but the one really wanted feature in ASP.NET web forms I'd guess is: Multiple forms! I know it's probably very difficult to implement with the current webforms architecture though, and wouldn't be as helpful for existing projects, but for new projects, that would be the only reason I'd "happily" create a new webforms project.
September 09, 2012 15:55
great stuff Scott, is it possible to switched off view state etc from aspx pages using new mvc like model forms?, so that we can get clean html page :).
September 09, 2012 19:05
Much awaited feature for Webforms. Thanks for sharing Scott. These features motivate us to learn mobile web development.
Thanks for sharing. Special thanks to Damian and Pranav :)
September 09, 2012 20:23
Suminda you can selectively turn off viewstate for the page or for some controls if you do not need viewstate
http://msdn.microsoft.com/en-us/library/system.web.ui.control.viewstatemode.aspx
September 10, 2012 6:27
This is cool, but does the mobile view stuff have any dependencies on the stuff behind this show-stopper?

Multiple DisplayModes - Caching error, will show wrong View

That bug is killing me, because it essentially breaks the alternate views. If they have different or additional @sections, and the cache breaks, you get 500's all over the place.
September 10, 2012 9:31
Thanks Jeff for the tip... I have taken note of this to make sure (if we have the same issue in FriendlyURLs as MVC's mobile implementation) this is fixed before we release the final version
September 10, 2012 18:22
This looks great, but my biggest problem with friendly URLs and Web Forms is that the Application_Error method in your Global.asax is not hit if you drop the ".aspx" extension and throw an error on that page. Any chance this works around that issue?
September 10, 2012 18:26
Thanks for this feature but we know now we have a helper method to build segments but what about any helper method in order to build a query string like :

FriendlyUrl.HrefWithQueryString("~/Foo", "bar", 34) %>

which ends up being

http://www.something.com/foo?bar=34

September 10, 2012 19:31
Thank you!
Don
September 10, 2012 20:13
@Jeff Putz, ASP.NET Friendly URLs has no dependency on the MVC/Web Pages mobile support and thus doesn't suffer from that bug. Of course if you find any issues please let us know.
September 10, 2012 20:58
We have an application that still needs to run in IIS5.1 (Windows XP).

does this work natively in IIS5.1 or would it be like routing for MVC and we would still need to add a custom mapping to the aspnet_isapi?
September 10, 2012 21:01
Every tool/feature with 'magic' needs to have a 'show me the magic' mode built in where it will dump why it did/chose something to the debug console for troubleshooting. I don't want to have to throw in random route troubleshooting tools, they should be built in!

Nice work on the urls, keep it up - looking forward to when it will be easy to configure at runtime.
Jed
September 10, 2012 21:16
Thats pretty awesome. It solves a problem I was going to have very shortly!
September 11, 2012 0:34
Rob, I cannot repro your issue. The application_end method in global.asax is called if you throw an exception from your page and browse to the page(minus the aspx extension)
September 12, 2012 3:00
I believe it was you who once quoted you as saying, "The less you do, the more of it you can do." So please help us do less by posting nuget commands as text instead of images that can't be cut/pasted! :P

Anyway, it looks like FriendlyUrls may make up for the lost keystrokes - thanks!
September 12, 2012 3:10
Pastey - Did you notice that the NuGet string *is* in the ALT text? ;)
September 12, 2012 14:12
This is great. My only question is - is there a definitive list of all Microsoft supported NuGet packages somewhere, as the list is getting quite large. And perhaps more importantly the status of those packages etc.
September 13, 2012 1:20
Sam - We are working on JUST this! I hope for a microsoft.nuget.org soon, myself. Like 'author.nuget.org'
September 13, 2012 16:52
How is the performance when compared to the url rewriting using Httpmodule? Have you done any comparisons? Hope this will not have any significant impact on performance.
September 13, 2012 23:27
This is really cool! I have other questions:

when we started use following syntax in .aspx page, what made it work?

<% foreach (var segment in Request.GetFriendlyUrlSegments()) { %> <li><%: segment %></li><% } %>

Thanks!
Xiaohong Liu
September 13, 2012 23:59
Xiaohong - Which? The :? That's .NET 4 and above.
September 14, 2012 2:20
Thanks Scott, Never realize I could use <%...%> in web form aspx pages, thought only for MVC.

Added FriendlyUrls to my .NET 4 site, it works!

September 14, 2012 11:51
Scott, why dont you use it on your own blog :) ?
September 16, 2012 16:39
Is there any way to run this in a low trust, shared hosting environment?

Deploying it as-is yields this error, "Request for the permission of type 'System.Security.Permissions.SecurityPermission' failed".

Changing the trust level is not allowed at the current host.


thanks,
-brit
September 17, 2012 14:47
FriendlyUrl results in a conflict when there is a folder with the same name as the aspx page without the extension. What is your plan on handling that? Right now it gives priority for the folder name on a development computer.
September 19, 2012 20:19
Awesome! The only issue (for me) seems that the Page.PreviousPage() is broken with the re-written urls. Is there any way to get this to work??
September 23, 2012 22:23
I really like the idea of this, however this will break debugging on a page.

Is there any easy fix for this?
October 01, 2012 20:12
I tested this sample app one several mobile devices and it will automatically send the user to the Mobile specific version of the application by default with iPhones and Windows Mobile phones.

I try hitting the URL with several Android phone browsers and it takes me to the Desktop templates by default.

Anyone have any insite on how to fix this issue for Android phones?
October 01, 2012 23:46
Mike, I suspect you could use 51Degrees.mobi to enhance the base information provided to .NET so that Android, and all other mobile platforms are better supported. Also the IsMobileExtension override in the example code looks like it could be upgraded to check for other properties such as tablets. James
October 15, 2012 17:31
OK, this sound great, BUT.... as far I can see we have to "rewrite" our project in order to make it work.

I assumed that :

1)< a href="~/About.aspx?id1=123&id2=987" runat="server">Tester < /a> would automaticly be transformed into a friendly version

2) Request.QueryString["id1"] would automaticly work when having a friendly url like "/About/id1/123"

But now we have to rewrite all our links manually AND we have to rewrite all our "getters" with the use of "GetFriendlyUrlSegments()"

Is this true or do I miss something crucial and that it already works this way? :)
November 15, 2012 4:37
Amazing!

Thank you Scott. It's exactly that I need.
November 15, 2012 21:00
man , you are amazing and helpful
November 28, 2012 21:32
How could I redirect to a completely different site if the Display Mode is NOT a Phone or a Tablet?
December 07, 2012 19:37
To make it work you need to add:
using System.Web.Routing;
into global.asax as well not only
RouteConfig.RegisterRoutes(RouteTable.Routes);

great article!
January 15, 2013 20:48
Hello,
I'd like to use this package but I get the following error:
"The name 'RouteConfig' does not exist in the current context".
I just added:
using System.Web.Routing;
...
protected void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
Could you help me please?
January 15, 2013 23:51
Same error here with an empty website...
January 24, 2013 19:03
Nice stuff!! Group can you help me to get it working?
I'm using VS 2012 (VB.NET). I have 2 questions:
1. When I call Routes.enablefriendlyurls as indicated in this article, I get the following error: Routes.enablefriendlyurls is not a member of System.Web.Routing.RouteCollection. Why?

2. Take the following example:
How can I rewrite the url Index.aspx?articleid=123456&languageid=EN as
"Index/123456/EN"
Does someone have a working example in VB or C#?
You can mail it to mobileboy36@gmail.com

Thank you group!

Best regards.
January 25, 2013 21:11
I'm getting the same issue as reported by Cesar and Jeff.

Clean asp.net Webforms 4.5 project.
"The name 'RouteConfig' does not exist in the current context".

using System.Web.Routing;
...
protected void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
Rui
January 25, 2013 21:17
OK... Fixed above issue. You must also now install (from NUGET) this : Microsoft.AspNet.FriendlyUrls.ViewSwitcher.

It seems like the latest build split out some features and dependencies into 2 packages.....just wondering what was the reason why the first package didn't also automatically pull in the 2nd package?

Rui
January 26, 2013 0:17
Rui - This from the authors: "we messed up the packages in RC. Will be fixed in RTW."

Yes you are right, include both packages and it will work. This will be fixed when it releases.
January 31, 2013 4:19
I have Two issues!


1# If i call my URL passing parameters, like:

www.mywebsite.com/page/parameter

The "page.aspx" is called two times... (not post back) it´s two different requests by differents threads.


2# if my page have images with status 404 (not found images) and if i´m calling this page with parameters, i have N different requests o my page, where N = Number of images with 404 status.


could someone help-me?






February 06, 2013 7:49
The ViewSwitcher is in C# and my project is VB, it seems like the C# code is not compiling.
Microsoft.Web.Infrastructure seems to be required but is not loaded as a dependency.

Is there a more complete example for using the ViewSwitcher, I am using the standard Site.Master from Visual Studio 2012 and the Site.Mobile.Master does not look anything like it, it looks like something from Visual Studio 2008 or 2010.
February 20, 2013 16:16
Hi Scott,

I am having problems trying to perform an .ajax() call with friendly URLs enabled

when
: the url = 'MyPage.aspx/MyMethod', i received a 401 Authentication failed error.

: the url = 'MyPage/MyMethod', i received the entire page page in the response

after I've commented out the "routes.EnableFriendlyUrls();"

the call is successful with the expected Response.

Is there any workaround for this?


$.ajax({
type: "POST",
url: 'MyPage.aspx/MyMethod',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "text",
async: true,
cache: false,
success: function (result) {
alert('success');
},
error: function (x, e) {
alert(x.responseText);
}


Thanks
Adlie
February 20, 2013 20:47
Hey,

I'm trying this new FriendlyUrls feature but for some reason I don't get that 301 redirect when I access the page with the ".aspx" extension. If I remove it manually everything works as expected.

Any idea why?
February 20, 2013 23:21
Question: Can we remove the site.mobile.master with no adverse effects? Or is there a way to programatically not call this masterpage when a user hits the site on a mobile device?
I really only want the simplified way of having friendly urls.
We're designing a website using media quieries so the mobile view will be delivered based on that.
Yes, we can split the responsive media queries into seperate css files to work with the mobile master...but it's not exactly clean since we'll now have 2 master pages to update (ie if menu needs updating)
Rui
February 21, 2013 23:02
@Rui - Yes, it's safe to delete. If it's not there, we won't use it :)
February 21, 2013 23:03
@Paulo - The auto-redirect was turned off for RTW as it can cause issues with some 3rd party handlers. You can turn it on again by passing a FriendlyUrlSettings object to the EnableFriendlyUrls method with the RedirectMode property set to an appropriate value.
February 23, 2013 7:54
Really great! Thank you so much for share it.
February 26, 2013 20:25
Damian, thanks! :)
February 27, 2013 1:20
I am lost, please help. I installed FriendlyURL from NuGet, ported the .cs code to .vb, added the DeviceSpecificWebFormsFriendlyUrlResolver class, added routes.EnableFriendlyUrls() to global.aspx.
Nothing in the resolver class is called and nothing .mobile ever gets called. I am using Visual Studio 2012 and VB. I did not notice any changes in web.config, yet the file get refreshed in the IDE, could that be the issue?
February 27, 2013 1:31
UPDATE:
I have added the two lines below and they have had no effect.
Dim settings As New FriendlyUrlSettings
settings.AutoRedirectMode = RedirectMode.Permanent
routes.EnableFriendlyUrls(settings)
March 02, 2013 0:29
RouteConfig.RegisterRoutes(RouteTable.Routes)

The class RouteConfig is not found.

VS 2010 VB.net Project?
March 02, 2013 1:12
To get Friendly Urls to work do the following:

1. Install the 2 following NuGet Packages
- Install Microsoft ASP.NET Friendly URLs - Core
- Install Microsoft ASP.NET Friendly URLs.

2. Read the "readme.txt" that gives you the next instructions.

3. Update your Global.asax.
<%@ import Namespace="System.Web.Routing" %>

4. Add the following call in your Application Start of Global.asax:
RouteConfig.RegisterRoutes(RouteTable.Routes)

Note: If your getting the error "RouteConfig" is not found you didn't install both friendly url packages above.

Tech Note: The Friendly Url Core Package will install a New Start Folder that contains classes and methods to support friendly urls. In VS 2010 look for the App_Start folder under the App_Core folder.
That's it, I hope this helps.
These instructions are for the ASP.NET Friendly URLs v1.0.0. Not the Pre-Release.

Mike - Giving Back after taking so much. :)
March 09, 2013 9:24
Hi

Does anyone know how to use PageMethods with this AspNetFriendlyUrl's enabled?


Thanks
Adlie
March 17, 2013 19:17
Does the FriendlyURL package work with web site projects?
Or any web application projects?
March 17, 2013 19:18
Does the FriendlyURL package work with web site projects?
Or only web application projects?
March 29, 2013 11:09
I've added both package and routing is not working, i'm using vs 2012 and my project type is Web Application 4
March 29, 2013 12:13
I have an web application project in visual studio 2012, i've added the required packages and routing is not working.I'm still getting .aspx suffix.

I started my project as Empty web application and added my webforms myself.Can these be the problem.
March 29, 2013 13:26
I've solved this problem
I manually removed .aspx suffix from all refernces, as Scott explained i thought that referncing the package will automatically remove the suffix.
April 02, 2013 1:21
Scott,

Does this package work in Classic mode?
April 09, 2013 5:39
What's the best way to test the switch to the mobile version of a page? I've been testing with my Windows Phone (Nokia Lumia 920), and I can only get the desktop version of the site.
May 10, 2013 18:36
For VB.Net folks, rename App_Code\App_Start\RouteConfig.cs to RouteConfig.vb, and replace the contents with:

Imports System
Imports System.Collections.Generic
Imports System.Web
Imports System.Web.Routing
Imports Microsoft.AspNet.FriendlyUrls

Namespace ASP
Public Module RouteConfig
Public Sub RegisterRoutes(routes As RouteCollection)
routes.EnableFriendlyUrls()
End Sub

End Module
End Namespace
May 14, 2013 0:09
I've said before how surprised I am that more ASP.NET Web Forms developers don't use Routing to make their URLs prettier.

Guys, here is the big secret: the customers do not care how your site's URLs look. The only URLs a user types into the browser are filenameless home page URLs that use default pages. The rest are only used in links. Users care about as much about how URLs look as they care about the style of a web site's source code.

The big value of URL rewriting is for mobile views to more easily support mobile devices. If you are using URL rewriting just to make your URLs prettier, you are wasting your time.
May 17, 2013 20:54
Hi Scott,
This is a nice ASP.NET UrlRouting tool I have ever tried nowadays. I devepoed a asp.net web form app using this tool. Its great working my local IIS. If I deploy to my web hosting, its giving an error about SecurityPermission.
Please help me!
Thanks a lot.

Exception: System.Security.SecurityException

Message: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

StackTrace: at System.Web.Hosting.HostingEnvironment.RegisterObject(IRegisteredObject obj)
at Microsoft.AspNet.FriendlyUrls.Abstractions.HostingEnvironmentWrapper.RegisterObject(IRegisteredObject obj)
at Microsoft.AspNet.FriendlyUrls.Caching.StaticFileCacheRunner.GetAllFilenamesInApplication()
at Microsoft.AspNet.FriendlyUrls.Caching.StaticFileCache.<>c__DisplayClass2.<.ctor>b__0(Object _)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
May 31, 2013 18:51
Hi. Adlie did you solved the problem using ajax call or pagemethods?
June 01, 2013 0:33
Yes, I just realized today that PageMethods do not work when using friendly url's. Has anyone found a solution for this?
June 24, 2013 8:56
Yalcin,
I am having the same issue with GoDaddy. The odd thing is it was working when I had basic hosting, when I upgraded to Deluxe Hosting it stopped working. Deluxe hosting also came with ASP.NET 4.5 instead of 4.0 so that might have something to do with it. GoDaddy's solution was to disable global.asax on my account (not useful).

I know GoDaddy does not support "FullTrust" on shared accounts but that would not explain why it works on Basic Hosting.

Anyone know what is going on?
July 03, 2013 10:29
Firstly, I would like to congratulate and thank you for coming up with such an exciting feature with Microsoft ASP.NET. Personally, I liked the option of switching between the Mobile view and desktop view. Awesome!!
July 10, 2013 13:29
I have some troubles using Friendly Urls and static ressources like .js or .css files.

It is the same as described here:
http://forums.asp.net/t/873722.aspx/1?Locating+Javascript+file+using+Friendly+URLs

it happens that if you use FriendlyUrl.Href("~/Details", "param") and have the URL "/Details/param?key=value" that all the files used in script tags like src="js/details.js" the request is sent to the page with the request URL "Details/js/details.js" instead of "js/details.js"

If you don't use any parameter after the page name it works fine. Is there any solution without rewriting all references in the project?
July 12, 2013 3:13
Manfred: Because you're passing a parameter to the Href() API, it's adding it as an extra segment to the URL. So you end up requesting the ~/Details.aspx page as “foo.com/Details/param”

Any relative paths in that page will now be treated as relative to ~/Details, as you’d expect.

To fix it, as always, scripts and other resources should not be referenced statically, but rather resolved from app relative root, e.g. ResolveUrl("~/js/details.js")
July 17, 2013 15:35
Thank you for the answer. This is what I have expected.

Maybe it is better to rewrite all inline included references to ResolveUrl("~") for static ressources anyway.
August 04, 2013 20:46
For ASP.NET MVC please check out this package I've created: https://www.nuget.org/packages/LowercaseDashedRoute/
And read the one-line configuration here: https://github.com/AtaS/lowercase-dashed-route
August 09, 2013 15:23
The following route declaration redirects perfectly for me

routes.MapPageRoute("Search", "search-directory/{searchterm}", "~/Directory.aspx");

but Request.GetFriendlyUrlSegments() returns nothing in Directory.aspx. How can I get the parameter passed?

August 11, 2013 0:30
When are these guys going to release the source code?
August 12, 2013 19:27
Hi
This is awesome plugin for URL friendly rewrite.
I Just found on Google and i was trying to on my project but it is not working for me.
it giving me errors are below :
1. "Could not load type 'ASP.Site_Mobile' "
2. "Could not load type 'ASP.ViewSwicther' "

Please help me.

Thanks
Vik
August 25, 2013 10:23
I was getting an error when using this statement:
<% foreach (var segment in Request.GetFriendlyUrlSegments()) { %>
  • <%: segment %>

  • <% } %>

    // C#: Several methods are applicable to: ... same methods though.


    this worked:
    <% foreach (var segment in HttpRequestExtensions.GetFriendlyUrlSegments(this.Request)) { %>
  • <%: segment %>

  • <% } %>
    Ray
    August 28, 2013 16:12
    Hi Scott,

    Will this work in a situation where one uses web forms within MVC?

    I'm asking this because my MVC projects have web forms that host reports using the Report Viewer Control.
    September 19, 2013 17:56
    While this library is great, the documentation is awful, and the source code still isn't available after a year.
    September 26, 2013 22:24
    Did anyone solve that Ajax/ web page method problem? I have tried to few things and Bing'd but had no luck so far.
    October 04, 2013 17:04
    Awesome article, managed to implement in relatively quick time. One thing I'm struggling with is where I can customise what is classed as a mobile device. Has anyone had any success with this?

    e.g. I want only iPhone to be classed as a mobile device and all others to be served the desktop version by default.

    Thanks again!
    October 07, 2013 21:48
    Danny - You could clear out the displayModes collection and insert just ONE:


    DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone") {
    ContextCondition = ctx => ctx.GetOverriddenUserAgent().Contains("iPhone")
    });
    October 11, 2013 16:26
    Great job!!!

    But there's a thing i dont know how it works.
    How can i get querystring mapped values?
    I know its possible via foreach ...segments
    But, is there any way for getting a value like in Request.QueryString["id"] ?

    Thanks in advance.
    October 14, 2013 14:51
    I'm looking at implementing URL Routing on an ASP.NET Web Forms website. I've been looking at the best way to handle 404 errors so for example:


    routes.MapPageRoute("NewsRouteArticle", "news/article/{url}", "~/news.aspx")


    The URL is matched against a news article in the database.

    What happens if a news article no longer exists? How can a handle this and redirect the user to the Custom Error page? I'm aware of the issue that exists with ASP.NET where 404 Errors actually give a status code of 302 and want to try and avoid this issue (see http://imar.spaanjaars.com/497/proper-handling-of-404-errors-using-redirectmode).
    October 20, 2013 13:57
    @Adlie Hendricks, @Omer
    I just saw your questions last night, I was also facing same problem with FriendlyURLs. I know its too late but I have found a solution by my self.
    Use direct call to a C# function from ajax, here is a post, it will help you how to call a C# function from ajax.

    <a href"http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/">http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/</a>
    October 21, 2013 0:23
    I wanted to loop back on the ajax thing. To ignore routes for .axd files I use - probably work for AJAX calls too.

    routes.Add(new Route("{resource}.axd/{*pathInfo}", new StopRoutingHandler()));

    Jeremy - regarding error pages... here is my routeconfig.cs entry

    routes.MapPageRoute("errors", "error/{friendlyurl}/{*pathInfo}", "~/error/default.aspx");

    and the web.config contains...
    <customErrors mode="On" defaultRedirect="/error/technical-difficulties" redirectMode="ResponseRewrite">
    .....
    <error statusCode="404" redirect="/error/file-not-found"/>
    </customErrors>

    while the <system.webServer> entry is

    <httpErrors>
    ....
    <remove statusCode="404" subStatusCode="-1"/>
    <error statusCode="404" prefixLanguageFilePath="" path="/error/file-not-found" responseMode="ExecuteURL"/>
    ....
    </httpErrors>

    Although, I would favor a message stating the news article does not exists when no records are returned from a database, on the news article page and use the 404 response for a more catch all type scenario.... It all depends on how your content is driven.

    Hope this helps.
    October 21, 2013 0:39
    Jeremy - your response status code can be set to 404 on page load. In fiddler for no records I see the response code as 404
    if (dT.Rows.Count == 0)
    {
    //send email to dl web development about link expiration.
    litCmsContent.Text = helpers.notFoundText();
    Response.StatusCode = 404;
    Response.Status = "404 Not Found";
    }

    October 21, 2013 18:33
    Hello, I'm having trouble getting this to work with the selected item of the asp.net Menu control.
    My sitemap contains urls with the .aspx extension. I don't want to change this because then the option securityTrimmingEnabled="true" of my sitemap provider won't work as expected.
    Could you point me in the right direction in order to fix this?

    Comments are closed.

    Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.