내 응용 프로그램에서는 종종 상대 경로를 사용해야합니다. 예를 들어, JQuery를 참조 할 때 일반적으로 다음과 같이합니다.
<script type="text/javascript" src="../Scripts/jquery-1.2.6.js"></script>
이제 MVC로 전환하고 있으므로 루트에 대해 페이지가 가질 수있는 다른 경로를 고려해야합니다. 물론 과거에는 URL 재 작성의 문제 였지만 일관된 경로를 사용하여 문제를 해결할 수있었습니다.
표준 솔루션은 다음과 같은 절대 경로를 사용하는 것임을 알고 있습니다.
<script type="text/javascript" src="/Scripts/jquery-1.2.6.js"></script>
그러나 이것은 개발주기 동안에는 작동하지 않습니다. 앱이 가상 디렉터리에서 실행될 테스트 컴퓨터에 배포해야합니다. 루트 상대 경로는 루트가 변경 될 때 작동하지 않습니다. 또한 유지 관리상의 이유로 테스트 배포 기간 동안 모든 경로를 간단히 변경할 수는 없습니다. 이는 그 자체로 악몽이 될 것입니다.
그렇다면 최상의 솔루션은 무엇입니까?
편집하다:
이 질문은 여전히 조회수와 답변을 받고 있기 때문에 Razor V2부터 루트 상대 URL에 대한 지원이 구워 져 있으므로 사용할 수 있도록 업데이트하는 것이 현명 할 것이라고 생각했습니다.
<img src="~/Content/MyImage.jpg">
서버 측 구문없이 뷰 엔진은 자동으로 ~ /를 현재 사이트 루트로 대체합니다.
답변
이 시도:
<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery-1.2.6.js")%>"></script>
또는 MvcContrib을 사용 하고 다음을 수행하십시오.
<%=Html.ScriptInclude("~/Content/Script/jquery.1.2.6.js")%>
답변
이전 게시물이지만 새로운 독자는 Razor 2 이상 (MVC4 +의 기본값)이이 문제를 완전히 해결한다는 것을 알아야합니다.
Razor 1을 사용하는 이전 MVC3 :
<a href="@Url.Content("~/Home")">Application home page</a>
Razor 2 이상이 포함 된 새로운 MVC4 :
<a href="~/Home">Application home page</a>
어색한 Razor 함수와 같은 구문이 없습니다. 비표준 마크 업 태그가 없습니다.
HTML 속성의 경로 앞에 물결표 ( ‘~’)를 붙이면 Razor 2는 올바른 경로를 대체하여 “작동하도록 설정”합니다. 훌륭합니다.
답변
브레이킹 체인지-MVC 5
MVC 5의 주요 변경 사항을 확인하십시오 ( MVC 5 릴리스 정보에서 ).
URL 재 작성 및 물결표 (~)
ASP.NET Razor 3 또는 ASP.NET MVC 5로 업그레이드 한 후 URL 재 작성을 사용하는 경우 물결표 (~) 표기법이 더 이상 올바르게 작동하지 않을 수 있습니다. 의 URL 재 작성과 같은 HTML 요소에서 물결표 (~) 표기법에 영향을 미치는
<A/>
,<SCRIPT/>
,<LINK/>
, 그 결과 물결표 더 이상 루트 디렉토리에 매핑합니다.예를 들어, 당신이 요청 다시 작성하는 경우 asp.net/content 에 asp.net을 ,의 HREF 속성
<A href="~/content/"/>
으로 확인
/ 컨텐츠 / 컨텐츠 / 대신에 / . 이 변경을 억제하려면 각 웹 페이지 또는 Global.asax의 Application_BeginRequest 에서 IIS_WasUrlRewritten 컨텍스트를 false로
설정할 수 있습니다 .
실제로 수행하는 방법을 설명하지는 않지만 다음 답변을 찾았습니다 .
IIS 7 통합 파이프 라인 모드에서 실행중인 경우 다음을 입력하십시오
Global.asax
.
protected void Application_BeginRequest(object sender, EventArgs e)
{
Request.ServerVariables.Remove("IIS_WasUrlRewritten");
}
참고 : 문제가 무엇인지 확인하기 위해 먼저 Request.ServerVariables
실제로 포함 을 확인하는 IIS_WasUrlRewritten
것이 좋습니다.
추신. 나는 이것이 나에게 발생하는 상황이 있다고 생각했고 src="~/content/..."
내 HTML에 URL을 생성하고 있었지만 내 코드를 컴파일 할 때 뭔가 새로 고쳐지지 않은 것으로 나타났습니다. 레이아웃 및 페이지 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>
내가 사용한 것입니다. 예제와 일치하도록 경로를 변경하십시오.
답변
그만한 가치가 있기 때문에, 나는 단지 경로를 확인하기 위해 서버 태그로 내 앱을 버리는 아이디어가 정말 싫습니다. 그래서 좀 더 조사를했고 링크를 다시 작성하기 위해 이전에 시도한 것을 사용하기로 결정했습니다-응답 필터. 이런 식으로 모든 절대 경로에 알려진 접두사를 접두사로 붙이고 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);
}
}
}
답변
MVC 3 용 Razor보기 엔진을 사용하면 런타임에 적절하게 확인되는 가상 루트 상대 경로를 더욱 쉽고 깔끔하게 사용할 수 있습니다. Url.Content () 메서드를 href 속성 값에 놓기 만하면 제대로 해결됩니다.
<a href="@Url.Content("~/Home")">Application home page</a>