ResolveUrl/ResolveClientUrl equivalents for Asp.Net Razor?
So I've started using the <%: Url.Content(~/site/blah) %>
syntax as standard for CSS, JScript and Image urls - solves a lot of issues indeed; and it's at least consistent beween WebForms and Razor pages (not all of my devs wi开发者_如何学Cll be doing Razor, and yet they will still be working on this platform I've produced).
However, for something that I'm doing at the moment I could really do with a way to take a relative Url written in a Razor page and, at run time, resolve it to the correct server side file, before turning it back into an absolute Url for the client. Url.Content
doesn't do anything with relative Urls.
So, basically, I want either an equivalent of ResolveUrl
or ResolveClientUrl
at the Razor level.
I would like this to enable terser (and more tolerant to renaming) resource paths in some of my MVC views, which can be a few folders further down from the root, and whose content folder would be more easily expressed as a relative path - so I could have:
folder\folder\views\shared\layout.cshtml
folder\folder\content\site.css
(I've inferred the use of a layout page, also, to mirror the kind of issues that are addressed by ResolveUrl and the re-basing that WebForms does)
Using Url.Content
as it is, I would need to specify the full path:
Url.Content("~/folder/folder/content/site.css")
But what I would like is
Url.Content("../../site.css")
And have that work, of course, regardless of how many paths there are in the current request's route.
Of course I can get this to work in WebForms, if I ditch the Url.Content call and just rely on url rebasing.
Is there any equivalent in Razor?
You could try using WebPageRenderingBase.Href method like this
@Href("../../site.css")
If you are converting ASP.NET application ASP.NET MVC step by step, you can use wrappers:
public abstract class ResolveClientUrlWrapper
{
public abstract string ResolveClientUrl(string relativeUrl);
}
public class ResolveClientUrlPageWrapper : ResolveClientUrlWrapper
{
System.Web.UI.Page _page;
public ResolveClientUrlPageWrapper(System.Web.UI.Page page)
{
_page = page;
}
public override string ResolveClientUrl(string relativeUrl)
{
return _page.ResolveClientUrl(relativeUrl);
}
}
public class ResolveClientUrlPWebPageRenderingBaseWrapper : ResolveClientUrlWrapper
{
WebPageRenderingBase _webPageRenderingBase;
public ResolveClientUrlPWebPageRenderingBaseWrapper(WebPageRenderingBase webPageRenderingBase)
{
_webPageRenderingBase = webPageRenderingBase;
}
public override string ResolveClientUrl(string relativeUrl)
{
return _webPageRenderingBase.Href(relativeUrl);
}
}
public class ResolveClientUrlUrlHelperWrapper : ResolveClientUrlWrapper
{
UrlHelper _urlHelper;
public ResolveClientUrlUrlHelperWrapper(UrlHelper urlHelper)
{
_urlHelper = urlHelper;
}
public override string ResolveClientUrl(string relativeUrl)
{
return _urlHelper.Content(relativeUrl);
}
}
public class PathUtilityWrapper : ResolveClientUrlWrapper
{
public override string ResolveClientUrl(string relativeUrl)
{
return VirtualPathUtility.ToAbsolute(relativeUrl);
}
}
You can ResolveClientUrlPageWrapper from classic ASP.NET page or ResolveClientUrlHttpServerUtilityBaseWrapper from ASP.NET MVC controller, ResolveClientUrlUrlHelperWrapper from ASP.NET MVC View. You will have the same background code accross the whole ASP.NET classic and ASP.NET MVC application.
I generally do it this way in my javascript code.
var imgUrl = '@Href("~/images/calendar.png")'
精彩评论