การส่งผ่านข้อมูลไปยัง Master Page ใน ASP.NET MVC


102

วิธีการส่งข้อมูลไปยัง Master Page (โดยใช้ ASP.NET MVC) โดยไม่ผิดกฎ MVC คืออะไร?

โดยส่วนตัวแล้วฉันชอบโค้ด abstract controller (ตัวควบคุมฐาน) หรือคลาสพื้นฐานซึ่งส่งผ่านไปยังมุมมองทั้งหมด


1
ฉันเขียนคำแนะนำเกี่ยวกับวิธีจัดการสิ่งนี้britishdeveloper.co.uk/2010/06/…น่าจะช่วยได้
BritishDeveloper

คำตอบ:


77

หากคุณต้องการให้มุมมองของคุณมีคลาสข้อมูลมุมมองที่พิมพ์มากสิ่งนี้อาจเหมาะกับคุณ วิธีแก้ปัญหาอื่น ๆ น่าจะถูกต้องกว่าแต่นี่เป็นความสมดุลที่ดีระหว่างการออกแบบและการใช้งานจริง IMHO

หน้าต้นแบบใช้คลาสข้อมูลมุมมองที่พิมพ์อย่างรุนแรงซึ่งมีเฉพาะข้อมูลที่เกี่ยวข้องเท่านั้น:

public class MasterViewData
{
    public ICollection<string> Navigation { get; set; }
}

แต่ละมุมมองที่ใช้หน้าต้นแบบนั้นจะใช้คลาสข้อมูลมุมมองที่พิมพ์อย่างรุนแรงซึ่งมีข้อมูลและได้มาจากข้อมูลมุมมองของหน้าต้นแบบ

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
}

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

public interface IViewDataFactory
{
    T Create<T>()
        where T : MasterViewData, new()
}

public class ProductController : Controller
{
    public ProductController(IViewDataFactory viewDataFactory)
    ...

    public ActionResult Index()
    {
        var viewData = viewDataFactory.Create<ProductViewData>();

        viewData.Name = "My product";
        viewData.Price = 9.95;

        return View("Index", viewData);
    }
}

การสืบทอดตรงกับต้นแบบเพื่อดูความสัมพันธ์ได้ดี แต่เมื่อพูดถึงการแสดงผลบางส่วน / การควบคุมผู้ใช้ฉันจะเขียนข้อมูลมุมมองของพวกเขาลงในข้อมูลการดูหน้าเว็บเช่น

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
    public SubViewData SubViewData { get; set; }
}

<% Html.RenderPartial("Sub", Model.SubViewData); %>

นี่เป็นโค้ดตัวอย่างเท่านั้นและไม่ได้มีไว้เพื่อคอมไพล์ตามที่เป็นอยู่ ออกแบบมาสำหรับ ASP.Net MVC 1.0


4
นี่เป็นวิธีที่แนะนำโดย Scott Gutherie ดังนั้นฉันต้องเห็นด้วย
Simon Fox

@ Simon Fox - มีลิงค์ไปยังคำแนะนำของ scottgu หรือไม่? ไม่พบ
orip


ขออภัย. มีปัญหาเล็กน้อยในการทำความเข้าใจส่วนนี้ คอนสตรัคเตอร์สำหรับคอนโทรลเลอร์ถูกส่งผ่านอินสแตนซ์ของ IViewDataFactory แต่ระบบคาดหวังว่าคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์ ฉันยังไม่คุ้นเคยกับไวยากรณ์ C # (โดยเฉพาะ "MasterViewData, new ()") สำหรับอินเทอร์เฟซ ใครช่วยอธิบายหรือชี้แหล่งข้อมูลที่ดีให้หน่อยได้ไหม ขอบคุณ.
Jason

5
ฉันชอบที่จะใช้โมเดลที่มีการพิมพ์อย่างชัดเจน แต่ฉันไม่ใช่แฟนตัวยงของการเชื่อมต่อข้อมูลหลักกับโมเดลและการกระทำอื่น ๆ ทั้งหมดของฉัน เข้ามาในหัวข้อนี้ช้าไปหน่อย แต่ฉันโพสต์แนวทางของฉันเกี่ยวกับข้อมูลหลักที่ช่วยให้ทุกอย่างหลวมขึ้น
Todd Menier

59

ฉันชอบที่จะหมดออกชิ้นที่ขับเคลื่อนด้วยข้อมูลของมุมมองต้นแบบที่เข้า partials และการแสดงผลโดยใช้Html.RenderAction สิ่งนี้มีข้อดีที่แตกต่างกันหลายประการเหนือวิธีการสืบทอดโมเดลมุมมองยอดนิยม

  1. ข้อมูลมุมมองหลักจะแยกออกจากโมเดลมุมมอง "ปกติ" โดยสิ้นเชิง นี่คือองค์ประกอบที่อยู่เหนือการถ่ายทอดทางพันธุกรรมและส่งผลให้เกิดระบบที่เชื่อมโยงกันอย่างหลวม ๆ ซึ่งง่ายต่อการเปลี่ยนแปลง
  2. โมเดลมุมมองหลักสร้างขึ้นโดยการทำงานของคอนโทรลเลอร์ที่แยกจากกันโดยสิ้นเชิง การดำเนินการ "ปกติ" ไม่จำเป็นต้องกังวลเกี่ยวกับเรื่องนี้และไม่จำเป็นต้องมีโรงงานข้อมูลการดูซึ่งดูซับซ้อนเกินไปสำหรับรสนิยมของฉัน
  3. หากคุณบังเอิญใช้เครื่องมือเช่นAutoMapperเพื่อแมปโดเมนของคุณกับโมเดลมุมมองของคุณคุณจะกำหนดค่าได้ง่ายขึ้นเนื่องจากโมเดลมุมมองของคุณจะใกล้เคียงกับโมเดลโดเมนของคุณมากขึ้นเมื่อไม่ได้รับช่วงข้อมูลมุมมองหลัก
  4. ด้วยวิธีการดำเนินการแยกต่างหากสำหรับข้อมูลหลักคุณสามารถใช้การแคชเอาต์พุตกับบางพื้นที่ของเพจได้อย่างง่ายดาย โดยทั่วไปมุมมองหลักจะมีข้อมูลที่เปลี่ยนแปลงน้อยกว่าเนื้อหาของหน้าหลัก

3
+1. ข้อดีอีกประการหนึ่งคือคุณสามารถมีมุมมองเดียวกันโดยใช้เพจต้นแบบที่แตกต่างกันขึ้นอยู่กับสถานะรันไทม์ปัจจุบัน
StriplingWarrior

1
ฉันชอบคำตอบนี้มาก - แนวทางอื่น ๆ ที่ระบุไว้ดูเหมือนจะซับซ้อนไปหน่อย
ข้าวเปลือก

2
นี่เป็นทางออกที่สง่างามที่สุดในความคิดของฉัน
autonomatt

1
วิธีนี้ดูเหมือนจะดีที่สุดสำหรับฉันเช่นกัน ขอบคุณล้าน!
JimDaniel

1
นี่เป็นวิธีที่ดี แต่อย่าลืมว่าคุณยังคงต้องระบุเส้นทางไปยัง "การดำเนินการบางส่วน" ของคุณ ดูคำตอบนี้stackoverflow.com/a/3553617/56621
Alex

20

แก้ไข

Generic Errorให้คำตอบที่ดีกว่าด้านล่าง โปรดอ่าน!

คำตอบเดิม

Microsoft ได้โพสต์ข้อความเกี่ยวกับวิธีจัดการนี้อย่างเป็นทางการ สิ่งนี้ให้คำแนะนำทีละขั้นตอนพร้อมคำอธิบายเหตุผลของพวกเขา

ในระยะสั้นพวกเขาแนะนำให้ใช้คลาสคอนโทรลเลอร์นามธรรม แต่ดูด้วยตัวคุณเอง


ขอบคุณ! ตัวอย่างนั้นคือสิ่งที่ฉันกำลังทำอยู่ ... หมวดหมู่ในทุกหน้ามาจากฐานข้อมูล
Martin

Scott Gutherie หนึ่งในผู้เขียน MVC แนะนำวิธีแก้ปัญหาโดย @Generic Error ด้านล่าง
Simon Fox

1
+1 เพื่อนำไปสู่คำตอบที่ดีที่สุดแม้ว่าคุณจะถูกต้องอย่างเป็นทางการและยอมรับว่าเป็นคำตอบของ OP ก็ตาม
IsmailS

+1 เพื่อนำไปสู่คำตอบที่ดีที่สุดแม้ว่าคุณจะถูกต้องอย่างเป็นทางการและยอมรับว่าเป็นคำตอบของ OP ก็ตาม
Dave Jellison

จริงๆแล้ว Todd Menier เป็นคำตอบที่ดีที่สุดสำหรับเรื่องนี้
andreialecu

7

ตัวควบคุมนามธรรมเป็นความคิดที่ดีและฉันยังไม่พบวิธีที่ดีกว่านี้ ฉันสนใจที่จะดูว่าคนอื่น ๆ ทำอะไรเช่นกัน



2

ฉันพบว่าพาเรนต์ทั่วไปสำหรับอ็อบเจ็กต์โมเดลทั้งหมดที่คุณส่งผ่านไปยังมุมมองนั้นมีประโยชน์อย่างยิ่ง

มักจะมีคุณสมบัติของโมเดลทั่วไประหว่างเพจอยู่ดี


0

วัตถุ Request.Params ไม่แน่นอน การเพิ่มค่าสเกลาร์เป็นส่วนหนึ่งของวงจรการประมวลผลคำขอนั้นค่อนข้างง่าย จากมุมมองของมุมมองข้อมูลนั้นอาจถูกจัดเตรียมไว้ใน QueryString หรือ FORM POST hth


0

ฉันคิดว่าวิธีที่ดีอีกวิธีหนึ่งคือการสร้างอินเทอร์เฟซสำหรับมุมมองกับคุณสมบัติบางอย่างเช่น ParentView ของอินเทอร์เฟซบางอย่างเพื่อให้คุณสามารถใช้ทั้งสองอย่างสำหรับการควบคุมที่ต้องการการอ้างอิงไปยังเพจ (การควบคุมหลัก) และสำหรับมุมมองหลักซึ่งควรเข้าถึงได้จาก มุมมอง


0

โซลูชันอื่น ๆ ขาดความสง่างามและใช้เวลานานเกินไป ฉันขอโทษที่ทำสิ่งที่น่าเศร้าและสิ้นหวังเกือบตลอดทั้งปีต่อมา:

<script runat="server" type="text/C#">
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        MasterModel = SiteMasterViewData.Get(this.Context);
    }

    protected SiteMasterViewData MasterModel;
</script>

เห็นได้ชัดว่าฉันมีเมธอด Get () แบบคงที่นี้บน SiteMasterViewData ที่ส่งคืน SiteMasterViewData


สำหรับหลาย ๆ คนสิ่งนี้อาจดูเหมือนแฮ็คหรือ 'ไม่สะอาด' แต่มันทำให้งานเสร็จเร็ว
argh

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