2016-08-02 66 views
1

我一直在閱讀基礎控制器,我似乎無法理解這個概念。我需要簡化控制器中的代碼,因爲我只是重複代碼罷了。我使用數據庫爲網站收集數據並構建一些列表以在視圖中使用。所有頁面共享我在基本控制器中複製的兩個列表。當我刪除pagescontroller中的列表時,我得到一個錯誤,名稱'滑塊'和'partenaires'在當前上下文中不存在。什麼是防止重複代碼的最好方法?訪問共享資源的基礎控制器或方法

這是我的基本控制器:

public class BaseController : Controller 
{ 
    PIAEntities db = new PIAEntities(); 

    public BaseController() 
    { 
     var sliders = db.Actualite.Where(a => a.Afficher).OrderByDescending(a => a.Date_publication); 
     var partenaires = db.Partenaire.Where(p => p.Afficher); 
    } 
} 

這是控制器的一部分管理我所有的

網頁
public class PagesController : BaseController 
{ 
    public PagesController() : base() 
    { 

    } 

    PIAEntities db = new PIAEntities(); 

    public ActionResult Activités() 
    { 
     var sliders = db.Actualite.Where(a => a.Afficher).OrderByDescending(a => a.Date_publication); 
     var partenaires = db.Partenaire.Where(p => p.Afficher); 
     var model = new ModelDeBase { Slider = sliders, Partenaire = partenaires }; 

     return View(model); 
    } 

    public ActionResult Actualités() 
    { 
     var sliders = db.Actualite.Where(a => a.Afficher).OrderByDescending(a => a.Date_publication); 
     var pageActualites = db.Actualite.OrderByDescending(a => a.Date_publication).Take(10); 
     var donateurs = db.Donateur.Where(d => d.Afficher); 
     var partenaires = db.Partenaire.Where(p => p.Afficher); 
     var model = new ModelActualite { Slider = sliders, Partenaire = partenaires, PageActualite = pageActualites, Donateur = donateurs }; 

     return View(model); 
    } 
} 

解決方案

好了,現在它的工作原理和我結束了在我的基地控制器中使用這個

public class BaseController : Controller 
{ 
    PIAEntities db = new PIAEntities(); 
    protected IEnumerable<Actualite> sliders { get; private set; } 
    protected IEnumerable<Partenaire> partenaires { get; private set; } 

    public BaseController() 
    { 
     sliders = db.Actualite.Where(a => a.Afficher).OrderByDescending(a => a.Date_publication); 
     partenaires = db.Partenaire.Where(p => p.Afficher); 
    } 
} 

和頁面控制器:

public class PagesController : BaseController 
{ 
    public PagesController() : base() 
    { 

    } 

    PIAEntities db = new PIAEntities(); 

    public ActionResult Activités() 
    { 
     var model = new ModelDeBase { Slider = sliders, Partenaire = partenaires }; 

     return View(model); 
    } 

    public ActionResult Actualités() 
    { 
     var pageActualites = db.Actualite.OrderByDescending(a => a.Date_publication).Take(10); 
     var donateurs = db.Donateur.Where(d => d.Afficher); 
     var model = new ModelActualite { Slider = sliders, Partenaire = partenaires, PageActualite = pageActualites, Donateur = donateurs }; 

     return View(model); 
    } 
} 
+2

你應該學習在C#中的繼承:https://msdn.microsoft.com/en-us/library/ms173149.aspx – blins

回答

1

無論您varaibles的,即sliderspartenaires訪問這些字段中BaseController構造的範圍中聲明,所以他們不會在構造函數外部訪問。

您應該在課堂上聲明他們爲private設置器,以便子類不能更改這些屬性。

public class BaseController : Controller 
{ 
    PIAEntities db = new PIAEntities(); 

    protected IEnumerable<Actualite> sliders { get; private set; } 

    protected IEnumerable<Paternaire> partenaires { get; private set; } 

    public BaseController() 
    { 
     this.sliders = db.Actualite.Where(a => a.Afficher).OrderByDescending(a => a.Date_publication); 
     this.partenaires = db.Partenaire.Where(p => p.Afficher); 
    } 
} 
+0

如果我將它們設置爲受保護,我會得到一個錯誤:不能用於這個區域因爲set訪問器是不可訪問的 –

+0

Nevernind這是私人設置,阻止我訪問 –

+0

@SteveMorin - 你應該能夠成功獲取值,它只是你將無法'設置',因爲私人訪問者。繼承是一件好事。但是如果你希望你的子類不應該改變這些值,你可以刪除私有訪問者。 :) – Yogi

1

以您目前的代碼,您要查詢Actualite的添加Partenaire的在BaseController的構造函數和你的PagesController是從繼承。但在您的活動操作方法中,您再次查詢相同的數據!當用戶請求Pages/Activites時,它將在您的活動控制器中執行您的BaseController構造函數代碼和代碼。所以你有重複的代碼。此外,您在BaseController構造函數中查詢的數據正在被設置爲一個變量(對於該方法而言是局部範圍的),並且不會在其他任何地方使用。你可以做的一件事是保留一些受保護的變量並分配給它。 您可以在您的子類中訪問這些受保護的變量。

public class BaseController : Controller 
{ 
    protected List<Actualite> Actualities {set;get;} 
    PIAEntities db = new PIAEntities(); 

    public BaseController() 
    { 
     this.Actualities = db.Actualite.Where(a => a.Afficher) 
          .OrderByDescending(a => a.Date_publication).ToList();    
    } 
} 

現在在您的PageController中,您可能只需用戶this.Actualites。你不需要再次查詢。

public ActionResult Activités() 
{ 
    var model = new ModelDeBase { Slider = this.Actualities }; 
    return View(model); 
} 

你可以爲你的其他收藏做同樣的事情。

由於您在構造函數中有該代碼,因此將調用任何從BaseController繼承的任何控制器的調用。但是你的一些操作方法可能不需要這些數據(但仍想要使用其他基本控制器變量/方法)。在這種情況下,我建議你將它移動到服務類別根據需要調用

public class PageService 
{ 
    public IEnumerable<Actualite> GetActualites() 
    { 
    return db.Actualite.Where(a => a.Afficher) 
           .OrderByDescending(a => a.Date_publication).ToList(); 
    } 
} 

現在在你的控制器,你創建一個這樣的對象,並根據需要調用GetActualites方法。

public ActionResult Activités() 
{ 
    var s=new PageService(); 
    var model = new ModelDeBase { Slider =s.GetActualites()}; 
    return View(model); 
} 

你可能會更進一步,提取一個接口並使用依賴注入框架注入具體的實現。這將幫助您單元測試您的控制器。

+0

這個服務類是非常有趣的。那麼最好將其用於僅針對某些頁面的其他所有列表? –

+1

爲您的數據創建服務類。例如,如果您想獲取有關產品的數據。創建一個ProductService類。如果您對編寫單元測試控制器感興趣,則應該爲該服務類創建一個接口並使用它。這裏是一個關於它的帖子,http://stackoverflow.com/questions/36389525/how-to-implement-dependency-injection-in-mvc – Shyju

2

你會得到那個錯誤,因爲現在你只是在構造函數的範圍內聲明對象。爲了解決這個問題,在構造函數之外聲明它們並在構造函數中設置值(不確定是否有正確的類型,必須從您的示例中扣除它們)。

public class BaseController : Controller 
{ 
    PIAEntities db = new PIAEntities(); 
    IQueryable<Actualite> sliders; 
    IQueryable<Paternaire> partenaires; 

    public BaseController() 
    { 
     sliders = db.Actualite.Where(a => a.Afficher).OrderByDescending(a => a.Date_publication); 
     partenaires = db.Partenaire.Where(p => p.Afficher); 
    } 
} 
0

你必須讓他們在基本控制器字段或屬性,現在你必須在構造函數中的局部變量,改變它是這樣的:

public class BaseController : Controller 
{ 
    PIAEntities db = new PIAEntities(); 

    // Fields added 
    protected IQueryable<Partenaire> partenaires ; 
    protected IQueryable<Actualite> sliders ; 

    public BaseController() 
    { 

     sliders = db.Actualite.Where(a => a.Afficher).OrderByDescending(a => a.Date_publication); 
     partenaires = db.Partenaire.Where(p => p.Afficher); 
    } 
} 

現在,您就可以在訪問其他控制器將從此基礎控制器繼承。

0

在您的基本控制器中添加幾個字段來保存滑塊& partenaires的值。然後你可以在構造函數中設置它們。

this._sliders = db.Actualite.Where(a => a.Afficher).OrderByDescending(a => a.Date_publication); 

然後,您應該能夠從派生控制器