ฉันจะระบุเลย์เอาต์ต่าง ๆ ในไฟล์ ViewStart ASP.NET MVC 3 ได้อย่างไร


313

ฉันต้องการมีเลย์เอาต์ 2 แบบในใบสมัครของฉัน สมมติว่าหนึ่งสำหรับส่วนสาธารณะของเว็บไซต์และอื่น ๆ สำหรับฝั่งสมาชิก

สำหรับความเรียบง่ายสมมติว่าตรรกะทั้งหมดสำหรับแต่ละเว็บไซต์เหล่านี้ถูกห่ออย่างเรียบร้อยเป็น 2 ตัวควบคุมที่แตกต่างกัน

  • PublicController
  • StaffController

และพวกเขาแต่ละคนมีเค้าโครงที่สอดคล้องกันสำหรับมุมมองทั้งหมดภายใต้แต่ละ

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

ฉันจะใช้ไฟล์ _ViewStart.cshtml เพื่อระบุว่ามุมมอง / การกระทำทั้งหมดภายใต้ "สาธารณะ" ใช้ PublicLayout และทุกอย่างภายใต้ "พนักงาน" ใช้ StaffLayout ได้อย่างไร

ขอบคุณ!


4
ในกรณี: หากคุณต้องการลบเค้าโครงสำหรับRazorมุมมองที่กำหนดให้ตั้งค่าLayout = null;
Leniel Maccaferri

3
เช่นเดียวกับความคิดเห็นในตัวอย่างของคุณคุณอาจไม่มีตัวควบคุมชื่อสาธารณะและพนักงาน ตัวควบคุมส่วนใหญ่มักจะถูกนำไปใช้เป็นจุดเริ่มต้นของการกระทำที่คล้ายกับ CRUD ในเอนทิตีทางธุรกิจที่สำคัญบางอย่างเช่น EventController, UserController หรือสิ่งที่คล้ายกัน หากใบสมัครของคุณมีขนาดใหญ่พอสมควรความรับผิดชอบของตัวควบคุมสาธารณะ / พนักงานจะเป็นเรื่องที่กว้างขวาง พิจารณาพื้นที่แทน msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspxคุณอาจทราบเรื่องนี้ แต่มีคนอื่นที่อ่านข้อความนี้อาจได้รับแนวคิดที่ผิดดังนั้นเพียงบันทึก
อเล็กซ์

คำตอบ:


558

คุณสามารถวาง_ViewStart.cshtmlไฟล์ไว้ใน/Views/Publicโฟลเดอร์ซึ่งจะแทนที่ไฟล์เริ่มต้นใน/Viewsโฟลเดอร์และระบุเลย์เอาต์ที่ต้องการ:

@{
    Layout = "~/Views/Shared/_PublicLayout.cshtml";
}

คุณสามารถใส่_ViewStart.cshtmlไฟล์อื่นเข้าไปใน/Views/Staffโฟลเดอร์ด้วย:

@{
    Layout = "~/Views/Shared/_StaffLayout.cshtml";
}

คุณสามารถระบุว่าควรใช้เลย์เอาต์ใดเมื่อส่งคืนมุมมองภายในแอ็คชันคอนโทรลเลอร์ แต่นั่นคือต่อการกระทำ:

return View("Index", "~/Views/Shared/_StaffLayout.cshtml", someViewModel);

ความเป็นไปได้อื่นคือตัวกรองการกระทำที่กำหนดเองซึ่งจะแทนที่เค้าโครง อย่างที่คุณเห็นความเป็นไปได้มากมายที่จะบรรลุเป้าหมายนี้ ขึ้นอยู่กับคุณว่าจะเลือกอันไหนดีที่สุดในสถานการณ์ของคุณ


UPDATE:

ตามที่ร้องขอในส่วนความคิดเห็นนี่เป็นตัวอย่างของตัวกรองการกระทำซึ่งจะเลือกหน้าต้นแบบ:

public class LayoutInjecterAttribute : ActionFilterAttribute
{
    private readonly string _masterName;
    public LayoutInjecterAttribute(string masterName)
    {
        _masterName = masterName;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = _masterName;
        }
    }
}

จากนั้นตกแต่งตัวควบคุมหรือการกระทำด้วยแอตทริบิวต์ที่กำหนดเองนี้ซึ่งระบุเค้าโครงที่คุณต้องการ:

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}

1
@DarinDimitrov ฉันจะสร้างLayoutInjecterAttributeที่ไหน ? มีสถานที่เฉพาะหรือไม่
kbvishnu

2
@VeeKeyBee คุณสามารถวางไว้ในActionFiltersโฟลเดอร์ย่อย
ดารินทินดิมิทรอฟ

ปัญหาหนึ่งที่อาจเกิดขึ้นกับLayoutInjecterAttribute: มันถูกเรียกใช้ก่อนOnExceptionวิธีของตัวควบคุม ดังนั้นหากคอนโทรลเลอร์ให้ผลลัพธ์มุมมองระหว่างการจัดการข้อยกเว้นเลย์เอาต์จะไม่ถูกตั้งค่า
เจฟชาร์ป

ในฐานะผู้ชายคนใหม่ของ MVC ฉันอยากจะขอบคุณสำหรับการสอนฉันมากในคำตอบนี้ OnActionExecutedแต่ผมไม่เข้าใจว่าอะไรที่เกิดขึ้นภายใน คุณช่วยอัพเดทคำตอบให้ฉันได้ไหม
Imad

29

อีกวิธีหนึ่งคือการกำหนดเค้าโครงภายในมุมมอง:

   @{
    Layout = "~/Views/Shared/_MyAdminLayout.cshtml";
    }

วิธีอื่น ๆ ที่สามารถทำได้สามารถพบได้ที่นี่หวังว่านี่จะช่วยให้ใครบางคน


1
สิ่งนี้จะไม่ทำงานหากไม่มี _ViewStart.cshtml แยกมุมมองของคุณจะยังคงแสดงอยู่ภายในวิธีการ @RenderBody () ในรูปแบบอื่น
Tillman32

นี้! ทำไมทุกคนถึงนำกระบวนการที่ซับซ้อนเหล่านี้ไปใช้เมื่อสิ่งที่คุณต้องทำคือ!
George Harnwell

15

วิธีนี้เป็นวิธีที่ง่ายที่สุดสำหรับผู้เริ่มต้นในการควบคุมการสร้างเลย์เอาต์ในแอปพลิเคชัน ASP.NET MVC ของคุณ เราสามารถระบุตัวควบคุมและแสดงเลย์เอาต์เป็นตัวควบคุมที่ตราไว้เพื่อทำสิ่งนี้เราสามารถเขียนโค้ดของเราในไฟล์ _ViewStart ในไดเรกทอรีรากของโฟลเดอร์ Views ต่อไปนี้เป็นตัวอย่างแสดงให้เห็นว่าสามารถทำได้

@{
    var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
    string cLayout = "";

    if (controller == "Webmaster")
        cLayout = "~/Views/Shared/_WebmasterLayout.cshtml";
    else
        cLayout = "~/Views/Shared/_Layout.cshtml";

    Layout = cLayout;
}

อ่านบทความฉบับสมบูรณ์ได้ที่นี่ "วิธีสร้างเค้าโครงที่แตกต่างใน ASP.NET MVC" ได้อย่างไร

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