Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISiteMapNodeUrlResolver.ResolveUrl requires returning a virtual path? #267

Closed
alexdresko opened this issue Jan 22, 2014 · 4 comments
Closed

Comments

@alexdresko
Copy link

Why does ISiteMapNodeUrlResolver.ResolveUrl require returning a virtual path? I can't seem to return a vastly different url such as http://asdf.com without getting the HttpException "'http://asdf.com' is not a valid virtual path".

@NightOwl888
Copy link
Collaborator

Firstly, you can use the url attribute/property to set the URL to one that is external to the application, which is the intended way to use an absolute URL.

<mvcSiteMapNode key="Microsoft" title="Microsoft" url="http://www.microsoft.com/"/>

However, if for some reason you still need to customize the ResolveUrl method after knowing this, you can transform your URL to a virtual path using the UrlPath helper class, as you can see in the default implementation of the SiteMapNodeUrlResolver.

return urlPath.MakeVirtualPathAppAbsolute(urlPath.Combine(urlPath.AppDomainAppVirtualPath, url));

As for "why", it is because the MVC infrastructure requires a virtual path. We also had some complaints that MvcSiteMapProvider didn't work if it were hosted in a sub-application (see #222 and #235) which led us to using this solution.

Unfortunately, at this time nesting the 3 method calls to the UrlPath helper is required - I haven't yet had a chance to consolidate these into a single method, so you will find this type of call used throughout MvcSiteMapProvider.

@NightOwl888
Copy link
Collaborator

One more piece of information I discovered that I left out. The UrlResolver is only called if the path is resolvable - that is, it is only called if the URL is not an absolute path. So if you set the URL property explicitly to "http://asdf.com", the UrlResolver will never be called.

However, I couldn't find anything in the code that would indicate that it is not possible to return an absolute URL from the UrlResolver. That is not the way the default implementation works, so that is an untested scenario.

If you are trying to create custom URLs, I recommend using the .NET routing infrastructure (by overriding RouteBase) to make custom routes rather than implementing ISiteMapNodeResolver. This will make the URLs work consistently in both MVC and MvcSiteMapProvider, so it is generally a better way to go.

The UrlResolver extension point was generally only useful to enforce lowercase URLs in .NET 3.5, but if you are using .NET 4.0 or higher, you can use the built-in LowerCaseUrls property of the RouteCollection so there is no need to do this within MvcSiteMapProvider anymore. Keep in mind that MVC 3 and higher don't even support .NET 3.5, so making a custom UrlResolver is something I would discourage at this point. It is only a thin wrapper around .NET routing, so you should be able to do whatever you want by changing your routes instead of MvcSiteMapProvider.

@NightOwl888
Copy link
Collaborator

Did my answer solve your issue, or is this still open?

@alexdresko
Copy link
Author

No, I don't think so. I don't want to set the url property to an http address. My custom ISiteMapNodeUrlResolver needs to determine at runtime which URL to return, and, ultimately UrlPath.CheckValidVirtualPath prevents ResolveUrl from returning anything with http://...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants