แสดงบางส่วนจากโฟลเดอร์อื่น (ไม่แชร์)


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

4
@Simon_Weaver คุณสามารถบรรลุเป้าหมายนั้นได้ วิธีหนึ่งก็คือการปรับเปลี่ยน ViewEngine และแทนที่เป็นFindPartialViewวิธีการด้วยสิ่งที่ต้องการif(partialViewName.Contains"/")partialViewName="~/Views/"+partialViewName;
Arnis Lapsa

2
ทำงานได้ในเครื่องยนต์ MVC 3 Razor เช่นกัน แต่เช่นเดียวกับข้างต้นคุณต้องมีส่วนขยาย (.cshtml)
Chris

หากอยู่ภายใต้ที่แตกต่างกันคุณจะต้องให้เส้นทาง "~ / พื้นที่ / TestArea / Views / Shared / _SomePartial.mobile.cshtml"
sandeep 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
เคอร์ติส Yallop

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 ในอนาคตและ Bingers ในอนาคต
Paul

- จะไม่ทำงานใน. Net Core 2.2 เนื่องจากไม่มี RazorViewEngine.PartialViewLocationFormats
Demian Berisford-Maynard

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

VirtualPathProviderViewEngine ซึ่งใช้ WebFormsViewEngine ควรสนับสนุนอักขระ "~" และ "/" ที่ด้านหน้าของพา ธ เพื่อให้ตัวอย่างของคุณทำงานได้

ฉันสังเกตเห็นตัวอย่างของคุณใช้พา ธ "~ / Account / myPartial.ascx" แต่คุณบอกว่าการควบคุมผู้ใช้ของคุณอยู่ในโฟลเดอร์ Views / Account คุณเคยลองไหม

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

หรือว่าเป็นเพียงพิมพ์ผิดในคำถามของคุณ?


3

สำหรับผู้อ่านที่ใช้ ASP.NET Core 2.1 หรือใหม่กว่าและต้องการใช้ไวยากรณ์ตัวช่วยแท็กบางส่วนลองสิ่งนี้:

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

tilde (~) เป็นตัวเลือก

ข้อมูลที่https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-3.1#partial-tag-helperก็มีประโยชน์เช่นกัน



0

สร้าง Custom View Engine และมีวิธีการส่งคืน 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


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.