Частичный рендеринг из другой папки (не общей)

StackOverflow https://stackoverflow.com/questions/208421

  •  03-07-2019
  •  | 
  •  

Вопрос

Как я могу заставить представление частично отображать (пользовательский элемент управления) из другой папки?С preview 3 я использовал для вызова RenderUserControl с полным путем, но при обновлении до preview 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 и в Общей папке.Но допустим, вы хотите добавить один.

Добавьте класс в вашу папку Models:

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

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

<%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 компонент маршрута не должен меняться, но в нашем коде пока, похоже, нет никаких недостатков в этом подходе.

Предполагается, что VirtualPathProviderViewEngine, на котором основан WebFormsViewEngine, поддерживает символы "~" и "/" в начале пути, поэтому приведенные выше примеры должны работать.

Я заметил, что в ваших примерах используется путь "~/Account/myPartial.ascx", но вы упомянули, что ваш пользовательский элемент управления находится в папке Views / Account.Вы пробовали

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

или это просто опечатка в вашем вопросе?

вы должны попробовать это

~/Views/Shared/parts/UMFview.ascx

разместите ~/Views/ перед вашим кодом

Создайте пользовательский механизм просмотра и создайте метод, который возвращает результат ViewEngineResult В этом примере вы просто перезаписываете _options.ViewLocationFormats и добавьте свою папку directory :

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

Попробуйте использовать RenderAction("myPartial","Account");

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top