Chr*_*ris 97 asp.net asp.net-mvc
在我的应用程序中,我经常需要使用相对路径.例如,当我引用JQuery时,我通常这样做:
<script type="text/javascript" src="../Scripts/jquery-1.2.6.js"></script>
Run Code Online (Sandbox Code Playgroud)
现在我正在转换到MVC,我需要考虑页面可能具有的相对于根的不同路径.这当然是过去URL重写的问题,但我设法通过使用一致的路径来解决它.
我知道标准解决方案是使用绝对路径,例如:
<script type="text/javascript" src="/Scripts/jquery-1.2.6.js"></script>
Run Code Online (Sandbox Code Playgroud)
但这对我来说不起作用,因为在开发周期中,我必须部署到应用程序将在虚拟目录中运行的测试机器上.根更改时,根相对路径不起作用.此外,出于维护原因,我不能简单地在部署测试期间更改所有路径 - 这本身就是一场噩梦.
那么什么是最好的解决方案?
编辑:
由于这个问题仍在接收观点和答案,我认为更新它可能是谨慎的,因为从Razor V2开始,支持根相对网址,所以你可以使用
<img src="~/Content/MyImage.jpg">
Run Code Online (Sandbox Code Playgroud)
没有任何服务器端语法,视图引擎自动替换〜/当前站点根目录.
Tim*_*ott 92
试试这个:
<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery-1.2.6.js")%>"></script>
Run Code Online (Sandbox Code Playgroud)
或者使用MvcContrib并执行以下操作:
<%=Html.ScriptInclude("~/Content/Script/jquery.1.2.6.js")%>
Run Code Online (Sandbox Code Playgroud)
Cha*_*rns 51
虽然是一篇旧帖,新读者应该知道Razor 2及更高版本(MVC4 +中的默认值)完全解决了这个问题.
使用Razor 1的旧MVC3:
<a href="@Url.Content("~/Home")">Application home page</a>
Run Code Online (Sandbox Code Playgroud)
使用Razor 2和更高版本的新MVC4:
<a href="~/Home">Application home page</a>
Run Code Online (Sandbox Code Playgroud)
没有笨拙的Razor函数式语法.没有非标准的标记标记.
使用波形符('〜')在任何HTML属性中添加路径,通过替换正确的路径告诉Razor 2"只使其工作".这很棒.
Sim*_*ver 10
注意MVC 5中的重大变化(来自MVC 5发行说明)
Url Rewrite和Tilde(〜)
升级到ASP.NET Razor 3或ASP.NET MVC 5后,如果使用URL重写,则波形符(〜)表示法可能无法正常工作.的URL重写影响HTML元素,如波浪线(〜)表示法
<A/>,<SCRIPT/>,<LINK/>,并且作为结果的波形符不再映射到根目录.例如,如果你重写的请求asp.net/content到asp.net,href属性
<A href="~/content/"/>解析为 /内容/内容/代替/.要禁止此更改,可以在每个Web页面或Global.asax 中的Application_BeginRequest中将IIS_WasUrlRewritten上下文设置为false .
他们实际上没有解释如何做到这一点,但后来我找到了这个答案:
如果您在IIS 7集成管道模式下运行,请尝试将以下内容放入
Global.asax:
protected void Application_BeginRequest(object sender, EventArgs e)
{
Request.ServerVariables.Remove("IIS_WasUrlRewritten");
}
Run Code Online (Sandbox Code Playgroud)
注意:您可能需要首先检查Request.ServerVariables实际包含IIS_WasUrlRewritten,以确保这是您的问题所在.
PS.我以为我遇到过这样的情况,我正在将src="~/content/..."URL生成到我的HTML中 - 但事实证明,当我的代码编译时,某些内容并不令人耳目一新.编辑和重新保存布局和页面cshtml文件以某种方式触发了一些工作.
在ASP.NET中我经常使用<img src='<%= VirtualPathUtility.ToAbsolute("~/images/logo.gif") %>' alt="Our Company Logo"/>.我不明白为什么类似的解决方案不适用于ASP.NET MVC.
<script src="<%=ResolveUrl("~/Scripts/jquery-1.2.6.min.js") %>" type="text/javascript"></script>
Run Code Online (Sandbox Code Playgroud)
是我用过的.更改路径以匹配您的示例.
对于它的价值,我真的很讨厌用服务器标签乱扔我的应用只是为了解决路径,所以我做了一些研究,并选择使用我之前尝试过的重写链接 - 响应过滤器.通过这种方式,我可以使用已知前缀为所有绝对路径添加前缀,并在运行时使用Response.Filter对象替换它,而不必担心不必要的服务器标记.代码发布在下面,以防它可以帮助其他任何人.
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
namespace Demo
{
public class PathRewriter : Stream
{
Stream filter;
HttpContext context;
object writeLock = new object();
StringBuilder sb = new StringBuilder();
Regex eofTag = new Regex("</html>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
Regex rootTag = new Regex("/_AppRoot_", RegexOptions.IgnoreCase | RegexOptions.Compiled);
public PathRewriter(Stream filter, HttpContext context)
{
this.filter = filter;
this.context = context;
}
public override void Write(byte[] buffer, int offset, int count)
{
string temp;
lock (writeLock)
{
temp = Encoding.UTF8.GetString(buffer, offset, count);
sb.Append(temp);
if (eofTag.IsMatch(temp))
RewritePaths();
}
}
public void RewritePaths()
{
byte[] buffer;
string temp;
string root;
temp = sb.ToString();
root = context.Request.ApplicationPath;
if (root == "/") root = "";
temp = rootTag.Replace(temp, root);
buffer = Encoding.UTF8.GetBytes(temp);
filter.Write(buffer, 0, buffer.Length);
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return filter.CanSeek; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Flush()
{
return;
}
public override long Length
{
get { return Encoding.UTF8.GetBytes(sb.ToString()).Length; }
}
public override long Position
{
get { return filter.Position; }
set { filter.Position = value; }
}
public override int Read(byte[] buffer, int offset, int count)
{
return filter.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return filter.Seek(offset, origin);
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
}
public class PathFilterModule : IHttpModule
{
public void Dispose()
{
return;
}
public void Init(HttpApplication context)
{
context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);
}
void context_ReleaseRequestState(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app.Response.ContentType == "text/html")
app.Response.Filter = new PathRewriter(app.Response.Filter, app.Context);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
89200 次 |
| 最近记录: |