source

ASP.NET MVC 상대 경로

factcode 2023. 6. 13. 22:49
반응형

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")%>

이전 게시물이지만, 새로운 독자는 레이저 2 이상(MVC4+의 기본값)이 이 문제를 완전히 해결한다는 것을 알아야 합니다.

레이저 1이 장착된 이전 MVC3:

<a href="@Url.Content("~/Home")">Application home page</a>

레이저 2 이상이 장착된 새로운 MVC4:

<a href="~/Home">Application home page</a>

어색한 레이저 함수와 유사한 구문이 없습니다.비표준 마크업 태그가 없습니다.

HTML 속성의 경로 앞에 타일드(~)를 붙이면 레이저 2가 올바른 경로를 대체하여 "그냥 작동하도록" 지시합니다.훌륭해.

변화를 깨는 - MVC 5

MVC 5(MVC 5 릴리스 노트에서)의 급격한 변경 사항을 주의하십시오.

URL 다시 쓰기 및 타일드(~)

ASP 3 ASP5로 한 후 ASP.NET Razor 3 는 ASP를 가 더 이상 수 .NET MVC 5로 업그레이드한 후 URL 다시 쓰기를 사용하는 경우 타일드(~) 표기법이 더 이상 올바르게 작동하지 않을 수 있습니다.URL 다시 쓰기는 다음과 같은 HTML 요소의 타일드(~) 표기법에 영향을 미칩니다.<A/>,<SCRIPT/>,<LINK/>결과적으로 타일드는 더 이상 루트 디렉토리에 매핑되지 않습니다.

예를 들어 asp.net/content 에 대한 요청을 asp.net 에 다시 쓰는 경우 href 특성은<A href="~/content/"/>/ 대신 /content/content/로 확인됩니다.이러한 변경을 억제하려면 각 웹 페이지 또는 Global.asax의 Application_BeginRequest에서 IIS_WasUrlRewrited 컨텍스트를 false로 설정합니다.

그들은 실제로 어떻게 하는지 설명하지 않지만, 저는 다음과 같은 답을 찾았습니다.

7 IIS 7에 을 입력합니다.Global.asax:

 protected void Application_BeginRequest(object sender, EventArgs e)
 {
     Request.ServerVariables.Remove("IIS_WasUrlRewritten");
 }

참고: 확인할 수 있습니다.Request.ServerVariables는 실로포 다니합함이 들어 있습니다.IIS_WasUrlRewritten이것이 당신의 문제인지 확인하기 위해 먼저.


PS.는 이런 있고 를 상황이 했습니다. 나는 내게 이런 일이 일어나고 있는 상황이 있다고 생각했고, 나는 점점.src="~/content/..."URL이 HTML에 생성되었지만 코드를 컴파일할 때 새로 고쳐지지 않은 것으로 나타났습니다.레이아웃 및 페이지 cshtml 파일을 편집하고 다시 저장하는 것이 작동을 유발했습니다.

ASP ASP를 합니다.NET에서는 주로 사용합니다.<img src='<%= VirtualPathUtility.ToAbsolute("~/images/logo.gif") %>' alt="Our Company Logo"/>ASP MVCASP.NET MVC에서 하지 않아야 하는

<script src="<%=ResolveUrl("~/Scripts/jquery-1.2.6.min.js") %>" type="text/javascript"></script>

제가 사용한 것입니다.예제와 일치하도록 경로를 변경합니다.

가치 있는 것은, 저는 경로를 해결하기 위해 앱에 서버 태그를 버리는 것이 정말 싫다는 것입니다. 그래서 저는 좀 더 조사를 해보고 링크를 다시 쓰는 데 이전에 시도했던 것인 응답 필터를 사용하기로 결정했습니다.이렇게 하면 모든 절대 경로에 알려진 접두사를 붙여놓고 응답을 사용하여 런타임에 이 접두사를 바꿀 수 있습니다.개체를 필터링하고 불필요한 서버 태그에 대해 걱정할 필요가 없습니다.코드는 다른 사람에게 도움이 될 경우를 대비하여 아래에 게시되어 있습니다.

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 view 엔진을 사용하면 런타임에 적절하게 해결된 가상 루트 상대 경로를 훨씬 더 쉽고 간편하게 사용할 수 있습니다.URL을 삭제하십시오.content() 메서드를 href 특성 값으로 변환하면 제대로 해결됩니다.

<a href="@Url.Content("~/Home")">Application home page</a>

Chris와 마찬가지로, 저는 단순히 뿌리부터 위를 바라보기 위해 제 깨끗한 마크업 안에 비대해진 서버 측면 태그를 넣어야 하는 것을 정말 참을 수 없습니다.그것은 매우 간단하고 합리적인 요구사항일 것입니다.하지만 저는 그런 간단한 일을 하기 위해 맞춤형 C# 수업을 작성하는 노력을 해야 한다는 생각도 싫어요. 왜 그래야 하죠?정말 시간 낭비야.

저는 단순히 "완벽함"을 훼손하고 경로 참조 내에서 가상 디렉터리의 루트 경로 이름을 하드 코딩했습니다.이런 식으로.

<script type="text/javascript" src="/MyProject/Scripts/jquery-1.2.6.js"></script>

URL을 해결하는 데 서버 측 처리나 C# 코드가 필요하지 않으므로 성능에 가장 좋습니다. 그래도 무시해도 될 것으로 알고 있습니다.서버 쪽의 더부룩하고 추악한 혼돈은 제 깨끗한 마크업에서 찾아볼 수 없습니다.

저는 이것이 하드 코드화되어 있고 그것이 http://MyDevServer/MyProject/ 대신 적절한 도메인으로 마이그레이션될 때 제거되어야 한다는 것을 알고 살아야 할 것입니다.

건배.

저는 간단한 도우미 방법을 사용합니다.보기 및 컨트롤러에서 쉽게 사용할 수 있습니다.

마크업:

<a href=@Helper.Root()/about">About Us</a>

도우미 방법:

public static string Root()
{
    if (HttpContext.Current.Request.Url.Host == "localhost")
    {
        return "";
    }
    else
    {
        return "/productionroot";
    }
}

언급URL : https://stackoverflow.com/questions/317315/asp-net-mvc-relative-paths

반응형