Відображати частково з іншої папки (не поділяється)


256

Як я можу зробити перегляд зробити частковим (керування користувачем) з іншої папки? За допомогою попереднього перегляду 3 я зателефонував до RenderUserControl по всьому шляху, але оновлення до попереднього перегляду 5 більше неможливо. Натомість ми отримали метод RenderPartial, але він не пропонує мені функціоналу, який я шукаю.

Відповіді:


443

Просто додайте шлях до подання з розширенням файлу.

Бритва:

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

Двигун ASP.NET:

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

Якщо це не ваша проблема, чи можете ви включити свій код, який працював з RenderUserControl?


19
Я б хотів, щоб ми могли просто сказати / AnotherFolder / Повідомлення
Simon_Weaver

4
@Simon_Weaver Ви можете цього досягти. Один із способів - змінити ViewEngine та замінити його FindPartialViewметод чимось на кшталтif(partialViewName.Contains"/")partialViewName="~/Views/"+partialViewName;
Арніс Лапса

2
Працює і в двигуні MVC 3 Razor, але, як і вище, вам потрібно розширення (.cshtml).
Кріс

Якщо його під різними, вам потрібно буде надати шлях "~ / Areas / TestArea / Views / Shared / _SomePartial.mobile.cshtml"
sandaep talabathula

Як ви обробляєте різні культури цього часткового перегляду (наприклад, ~ / Views / AnotherFolder / Messages.en.cshtml)?
jasdefer

29

У моєму випадку я використовував MvcMailer (https://github.com/smsohan/MvcMailer) і хотів отримати доступ до часткового перегляду з іншої папки, яка не була в розділі "Спільний". Вищезазначені рішення не спрацювали, але з використанням відносного шляху це було.

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

Аналогічно @ Html.Partial ("../ Shared / _PartialView") використовувати папку Shared.
Кертіс Яллоп

11
Я виявляю, що це не працює без розширення .cshtml наприкінці.
Лука

28

Якщо ви використовуєте цей інший шлях багато часу, ви можете це виправити постійно, не вказуючи весь шлях. За замовчуванням він перевіряє часткові перегляди в папці «Перегляд» та в папці «Спільне». Але скажіть, що ви хочете додати його.

Додайте клас до папки Моделі:

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

6
Звичайно, я усвідомлюю, що це питання було задано давно. Думав, що я додам його до майбутніх службовців Google та майбутніх бінгерів.
Павло

- Не працюватиме в .Net Core 2.2, оскільки RazorViewEngine.PartialViewLocationFormats не існує.
Дем'ян Берісфорд-Мейнард

7

Для управління користувачем з назвою myPartial.ascx, розміщеного в папці Views / Account, напишіть так:

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

5

Я створив обхід, який, здається, працює досить добре. Я виявив необхідність перейти на контекст іншого контролера для пошуку імені дії, пошуку перегляду тощо. Для цього я створив новий метод розширення для 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компонент маршруту не мінявся, але в нашому коді поки що, схоже, немає жодного негативу такому підходу.


4

ВіртуальнийPathProviderViewEngine, на якому базується WebFormsViewEngine, повинен підтримувати символи "~" та "/" в передній частині шляху, щоб ваші приклади вище працювали.

Я помітив, що ваші приклади використовують шлях "~ / Акаунт / myPartial.ascx", але ви згадали, що ваш контроль користувача знаходиться в папці Перегляди / Обліковий запис. Ти намагався

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

чи це просто помилка у вашому питанні?


3

Для читачів, які використовують ASP.NET Core 2.1 або пізнішої версії та хочуть використовувати синтаксис Partial Tag Helper , спробуйте це:

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

Тильда (~) не є обов'язковою.

Інформація на https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-3.1#partial-tag-helper також корисна.


0

ви повинні спробувати це

~/Views/Shared/parts/UMFview.ascx

розмістіть ~/Views/перед своїм кодом


0

Створіть користувальницький механізм перегляду та створіть метод, який повертає ViewEngineResult У цьому прикладі ви просто перезаписуєте _options.ViewLocationFormatsта додаєте каталог папок:

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

Приклад: https://github.com/AspNetMonsters/pugzor


-5

Спробуйте використовувати RenderAction("myPartial","Account");


3
Будь ласка, прочитайте питання, коли користувач запитує про перегляд у іншій папці, де папка у вашому коді?
Памма
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.