別のフォルダーから部分的にレンダリングする(共有されない)


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 / Messages
Simon_Weaver 2009年

4
@Simon_Weaverあなたはそれを達成することができます。1つの方法は、ViewEngineを変更して、そのFindPartialViewメソッドを次のようなものでオーバーライドすることですif(partialViewName.Contains"/")partialViewName="~/Views/"+partialViewName;
Arnis Lapsa

2
MVC 3 Razorエンジンでも動作しますが、上記と同様に、拡張子(.cshtml)が必要です。
Chris

異なる場合は、パス「〜/ Areas / TestArea / Views / Shared / _SomePartial.mobile.cshtml」を指定する必要があります
sandeep talabathula

その部分ビューの異なるカルチャをどのように処理しますか(たとえば、〜/ Views / AnotherFolder / Messages.en.cshtml)?
jasdefer 2017

29

私の場合、私はMvcMailer(https://github.com/smsohan/MvcMailer)を使用していて、「共有」されていない別のフォルダーから部分ビューにアクセスしたいと思っていました。上記のソリューションは機能しませんでしたが、相対パスを使用すると機能しました。

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

同様に、@ Html.Partial( "../ Shared / _PartialView")を使用して共有フォルダーを使用します。
Curtis Yallop

11
最後に.cshtml拡張子がないと、これは機能しません。
ルーク

28

この他のパスを頻繁に使用している場合は、常にパスを指定する必要なく、これを永続的に修正できます。デフォルトでは、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());

6
もちろん、私はこの質問がずっと前に尋ねられたことを理解しています。将来のGoogle社員や将来のBingersのために追加すると思います。
Paul

-RazorViewEngine.PartialViewLocationFormatsが存在しないため、.Net Core 2.2では機能しません。
Demian Berisford-Maynard

7

Views / AccountフォルダーにあるmyPartial.ascxという名前のユーザーコントロールの場合、次のように記述します。

<%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

WebFormsViewEngineのベースとなっているVirtualPathProviderViewEngineは、パスの先頭にある「〜」および「/」文字をサポートするため、上記の例が機能するはずです。

あなたの例ではパス「〜/ Account / myPartial.ascx」を使用していることに気付きましたが、ユーザーコントロールはViews / Accountフォルダーにあると述べました。やってみました

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

それともあなたの質問のタイプミスですか?



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
ユーザーがコード内のフォルダーは別のフォルダーでの表示について質問しているので、質問を読んでください。
2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.