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.