태그 보관물: asp.net-mvc

asp.net-mvc

ASP.NET MVC 상대 경로 다음과 같은

내 응용 프로그램에서는 종종 상대 경로를 사용해야합니다. 예를 들어, 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/contentasp.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>