[C#] 다른 폴더에서 부분 렌더링 (공유되지 않음)

다른 폴더에서 부분 (사용자 정의 컨트롤)을 렌더링하도록 뷰를 만들려면 어떻게해야합니까? 미리보기 3에서는 완전한 경로로 RenderUserControl을 호출했지만 미리보기 5로 업그레이드하는 동안 더 이상 불가능합니다. 대신 RenderPartial 메서드를 얻었지만 원하는 기능을 제공하지 않습니다.



답변

파일 확장자를 사용하여보기 경로를 포함하십시오.

면도칼:

@Html.Partial("~/Views/AnotherFolder/Messages.cshtml", ViewData.Model.Successes)

ASP.NET 엔진 :

<% Html.RenderPartial("~/Views/AnotherFolder/Messages.ascx", ViewData.Model.Successes); %>

이것이 문제가 아닌 경우, RenderUserControl과 작동하는 데 사용 된 코드를 포함시킬 수 있습니까?


답변

제 경우에는 MvcMailer (https://github.com/smsohan/MvcMailer)를 사용하고 “공유”에없는 다른 폴더에서 부분보기에 액세스하려고했습니다. 위의 해결책은 효과가 없었지만 상대 경로를 사용하는 것은 효과가 없었습니다.

@Html.Partial("../MyViewFolder/Partials/_PartialView", Model.MyObject)


답변

이 다른 경로를 많이 사용하는 경우 항상 경로를 지정하지 않고도 영구적으로 수정할 수 있습니다. 기본적으로 View 폴더와 Shared 폴더에서 부분보기를 확인합니다. 그러나 하나를 추가하고 싶다고 가정하십시오.

모델 폴더에 클래스를 추가하십시오.

public class NewViewEngine : RazorViewEngine {

   private static readonly string[] NEW_PARTIAL_VIEW_FORMATS = new[] {
      "~/Views/Foo/{0}.cshtml",
      "~/Views/Shared/Bar/{0}.cshtml"
   };

   public NewViewEngine() {
      // Keep existing locations in sync
      base.PartialViewLocationFormats = base.PartialViewLocationFormats.Union(NEW_PARTIAL_VIEW_FORMATS).ToArray();
   }
}

그런 다음 Global.asax.cs 파일에서 다음 줄을 추가하십시오.

ViewEngines.Engines.Add(new NewViewEngine());


답변

Views / Account 폴더에있는 myPartial.ascx라는 사용자 정의 컨트롤의 경우 다음과 같이 작성하십시오.

<%Html.RenderPartial("~/Views/Account/myPartial.ascx");%>


답변

나는 꽤 잘 작동하는 것처럼 보이는 해결 방법을 만들었습니다. 액션 이름 조회, 뷰 조회 등을 위해 다른 컨트롤러의 컨텍스트로 전환해야한다는 것을 알았습니다. 이것을 구현하기 위해 HtmlHelper다음과 같은 새로운 확장 방법을 만들었습니다 .

public static IDisposable ControllerContextRegion(
    this HtmlHelper html,
    string controllerName)
{
    return new ControllerContextRegion(html.ViewContext.RouteData, controllerName);
}

ControllerContextRegion 다음과 같이 정의됩니다.

internal class ControllerContextRegion : IDisposable
{
    private readonly RouteData routeData;
    private readonly string previousControllerName;

    public ControllerContextRegion(RouteData routeData, string controllerName)
    {
        this.routeData = routeData;
        this.previousControllerName = routeData.GetRequiredString("controller");
        this.SetControllerName(controllerName);
    }

    public void Dispose()
    {
        this.SetControllerName(this.previousControllerName);
    }

    private void SetControllerName(string controllerName)
    {
        this.routeData.Values["controller"] = controllerName;
    }
}

이것이 뷰 내에서 사용되는 방식은 다음과 같습니다.

@using (Html.ControllerContextRegion("Foo")) {
    // Html.Action, Html.Partial, etc. now looks things up as though
    // FooController was our controller.
}

코드에 controller경로 구성 요소가 변경되지 않아야 하는 경우 원하지 않는 부작용이있을 수 있지만 지금까지는이 방법에 부정적인 영향을 미치지 않는 것으로 보입니다.


답변

WebFormsViewEngine의 기반이되는 VirtualPathProviderViewEngine은 경로 앞의 “~”및 “/”문자를 지원하므로 위의 예제가 작동해야합니다.

예제에서 “~ / Account / myPartial.ascx”경로를 사용하는 것을 보았지만 사용자 컨트롤이 Views / Account 폴더에 있다고 언급했습니다. 당신이 시도 했습니까

<%Html.RenderPartial("~/Views/Account/myPartial.ascx");%>

아니면 당신의 질문에 오타입니까?


답변

ASP.NET Core 2.1 이상을 사용하고 부분 태그 도우미 구문 을 사용하려는 독자는 다음을 시도하십시오.

<partial name="~/Views/Folder/_PartialName.cshtml" />

물결표 (~)는 선택 사항입니다.

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-3.1#partial-tag-helper 의 정보 도 도움이됩니다.