Renderuj częściowo z innego folderu (nieudostępnione)


256

Jak mogę renderować widok częściowy (kontrola użytkownika) z innego folderu? W wersji zapoznawczej 3 wywoływałem RenderUserControl z pełną ścieżką, ale przy aktualizacji do wersji 5 nie jest to już możliwe. Zamiast tego mamy metodę RenderPartial, ale nie oferuje mi ona funkcji, której szukam.

Odpowiedzi:


443

Wystarczy podać ścieżkę do widoku z rozszerzeniem pliku.

Brzytwa:

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

Silnik ASP.NET:

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

Jeśli to nie jest twój problem, czy możesz dołączyć swój kod, który pracował z RenderUserControl?


19
Chciałbym tylko powiedzieć / AnotherFolder / Messages
— Simon_Weaver

4
@Simon_Weaver Możesz to osiągnąć. Jednym ze sposobów byłoby zmodyfikować ViewEngine i zastąpić ją za FindPartialViewmetodę z czymś takimif(partialViewName.Contains"/")partialViewName="~/Views/"+partialViewName;
— Arnis Lapsa

2
Działa również w silniku MVC 3 Razor, ale podobnie jak powyżej, potrzebujesz rozszerzenia (.cshtml).
— Chris

Jeśli jest inaczej, należy podać ścieżkę „~ / Obszary / TestArea / Views / Shared / _SomePartial.mobile.cshtml”
— sandeep talabathula

Jak radzisz sobie z różnymi kulturami tego częściowego widoku (na przykład ~ / Views / AnotherFolder / Messages.en.cshtml)?
— jasdefer

29

W moim przypadku korzystałem z MvcMailer (https://github.com/smsohan/MvcMailer) i chciałem uzyskać dostęp do częściowego widoku z innego folderu, który nie był w folderze „Shared”. Powyższe rozwiązania nie działały, ale działało przy użyciu ścieżki względnej.

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

Podobnie @ Html.Partial („../ Shared / _PartialView”), aby użyć folderu współdzielonego.
— Curtis Yallop

11
Zauważyłem, że to nie działa bez rozszerzenia .cshtml na końcu.
— Łukasz

28

Jeśli często używasz tej innej ścieżki, możesz to naprawić na stałe, bez konieczności ciągłego określania ścieżki. Domyślnie sprawdza częściowe widoki w folderze Widok i folderze współdzielonym. Ale powiedz, że chcesz go dodać.

Dodaj klasę do folderu Modele:

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();
   }
}

Następnie w pliku Global.asax.cs dodaj następujący wiersz:

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

6
Oczywiście zdaję sobie sprawę, że to pytanie zostało zadane dawno temu. Pomyślałem, że dodam to do przyszłych Googlerów i przyszłych Bingerów.
— Paul

- Nie będzie działać w .Net Core 2.2, ponieważ RazorViewEngine.PartialViewLocationFormats nie istnieje.
— Demian Berisford-Maynard

7

Dla kontrolki użytkownika o nazwie myPartial.ascx znajdującej się w folderze Views / Account napisz:

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

5

Stworzyłem obejście, które wydaje się działać całkiem dobrze. Znalazłem potrzebę przejścia do kontekstu innego kontrolera w celu wyszukiwania nazw akcji, wyszukiwania itp. Aby to zaimplementować, stworzyłem nową metodę rozszerzenia dla HtmlHelper:

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

ControllerContextRegion jest zdefiniowany jako:

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;
    }
}

Sposób użycia tego w widoku jest następujący:

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

Mogą występować niepożądane skutki uboczne, jeśli Twój kod wymaga, aby controllerskładnik trasy nie zmieniał się, ale do tej pory w naszym kodzie nie wydaje się, aby to podejście było negatywne.


4

VirtualPathProviderViewEngine, na którym oparty jest WebFormsViewEngine, powinien obsługiwać znaki „~” i „/” z przodu ścieżki, więc powyższe przykłady powinny działać.

Zauważyłem, że twoje przykłady wykorzystują ścieżkę „~ / Account / myPartial.ascx”, ale wspomniałeś, że twoja kontrola użytkownika znajduje się w folderze Views / Account. Czy próbowałeś

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

czy to tylko literówka w twoim pytaniu?



0

powinieneś tego spróbować

~/Views/Shared/parts/UMFview.ascx

umieść ~/Views/przed swoim kodem


0

Utwórz niestandardowy silnik widoku i zastosuj metodę, która zwraca ViewEngineResult W tym przykładzie po prostu nadpisujesz _options.ViewLocationFormatsi dodajesz katalog folderów:

public ViewEngineResult FindView(ActionContext context, string viewName, bool isMainPage)
        {
            var controllerName = context.GetNormalizedRouteValue(CONTROLLER_KEY);
            var areaName = context.GetNormalizedRouteValue(AREA_KEY);

            var checkedLocations = new List<string>();
            foreach (var location in _options.ViewLocationFormats)
            {
                var view = string.Format(location, viewName, controllerName);
                if (File.Exists(view))
                {
                    return ViewEngineResult.Found("Default", new View(view, _ViewRendering));
                }
                checkedLocations.Add(view);
            }

            return ViewEngineResult.NotFound(viewName, checkedLocations);
        }

Przykład: https://github.com/AspNetMonsters/pugzor


-5

Spróbuj użyć RenderAction("myPartial","Account");


3
Przeczytaj pytanie, gdy użytkownik pyta o widok w innym folderze, gdzie jest folder w twoim kodzie?
— Pamma,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.