2010-08-29 50 views
0

我剛剛進入.NET MVC2(即使是一般的.NET),我也很難熟悉事物的「流」。 MVC框架,我得到了..大部分。我被絆倒的部分是將標準編程實踐應用於.NET MVC。通用.NET MVC2問題

例如

public ActionResult Index() 
{ 
    var dataContext = new SiteContentDataContext(); 
    var data = from c in dataContext.SiteContents where c.Slug == "home-page" select c; 
    // call/return getMainNav() 
    // call/return getSubNav() 
    return View(data); 
} 

public ActionResult SiteContent(string strSlug) 
{ 
    var dataContext = new SiteContentDataContext(); 
    var data = from c in dataContext.SiteContents where c.Slug == strSlug select c; 
    // call/return getMainNav() 
    // call/return getSubNav() 
    return View(data); 
} 

private void getSubNav() 
{ 
    // get subnav records from db. 
    // return subnav records. 
} 

private void getMainNav() 
{ 
    // get main nav records from db. 
    // return main nav records. 
} 

指數和SiteContent視圖是不同的是在索引視圖使用一個不同的主頁的實際上是相同的。這兩個視圖都有一個subnav和一個主導航,它們將是來自數據庫的動態內容。

最後,問題是我將如何去填充getSubNav和getMainNav函數,其次,我將如何正確地返回數據到視圖?

+0

RenderPartial(@Manaf Abo.Rous)和ViewModel(@Tahbaza)答案都是幫助我理解.NET MVC2的更多內容。雖然我實際上是從ViewModel的方式'強制輸入'一個視圖,使用實體數據模型中的表格對象'輸入'一個視圖? – 2010-09-01 04:10:31

+0

Drats,我不能標記兩個答案! :( – 2010-09-01 04:11:09

回答

1

查看ViewModel對象,您創建的對象的目的是將數據傳入和傳出視圖。默認情況下在新MVC項目中爲您創建的模型文件夾將完全保留這些類。

除ViewModel對象方法外,您還有其他選項,但沒有一個是乾淨的。 (ViewData字典是爲了幫助,但它並不打算成爲向視圖提供數據的主要手段。)下面是如何將ViewData對象的Model屬性設置爲實例化,填充的視圖模型實例的示例:

public ActionResult SiteContent(string strSlug) { 
     SiteContentVM model = new SiteContentVM(); 
     SiteService siteService = new SiteService(); 
     model.Slug = siteService.GetALittleSlimyCreature(strSlug); 
     model.List1 = siteService.GetList1(); 
     model.List2 = siteService.GetList2(); 
     ViewData.Model = model; 
     return View(); 
    } 

現在,您可以創建一個強類型的視圖(完整的智能感知)來引用您的視圖模型的任何屬性,從您的視圖中的對象實例只需通過Model屬性:

<% foreach (var item in Model.List1) { %> 
    <% Html.Encode(item.StringField) %> <!-- <= writing a property --> 
    <% Html.RenderPartial("PartialNameHere", item); %> <!-- <= the equivalent of a usercontrol --> 
<% } %> 

正如你所看到的過程中上述從數據庫獲取數據不會改變MVC。你就像在一個正常的webforms項目中那樣做。 (...通常這涉及實例化某種業務邏輯或服務類,而不是實際在MVC項目中編寫代碼。)

享受MVC!

+0

你剛剛在我之前,我會補充說,如果主頁面需要數據,那麼你必須強制鍵入主頁面以及充分利用ViewModel,但確實存在的問題是所有使用母版頁將需要被強制輸入到該ViewModel或其子類 – 2010-08-29 01:15:29

+0

@Ian ,,你是對的,,,但有時你需要給主頁提供一些數據,比如導航鏈接,頁面標題等等。我發現擁有一個強類型的主頁面使事情變得容易一些,King Wilder有一個很好的方法來完成它,他使用一個BaseViewModel和一個BaseViewModelBuilder來簡化控制器中的事情,你可以查看他的Golf Tracker源代碼,看看他是如何做到的 http://www.mvccentral.net/Kit/Details/3/Golf_Tracker_Kit – 2010-08-29 03:46:24

+0

我認爲你是對的,我使用了類似的單一強類型mas ter頁面和所有視圖模型都繼承自該基本模型(這會強制您使用視圖模型),但如果您可能使用幾個不同的母版頁(可能需要幾個不同的基本模型),它確實會使工作更難一些 – 2010-08-31 14:12:47

1

嗯,,,我認爲你在這裏找的是部分視圖。

您可以將MainNav & SubNav視圖嵌入到您的SiteContent視圖中。

這是怎麼回事。

創建您的MainNav & SubNav作爲部分視圖。

在您的SiteContent視圖中使用Html.RendarPartial方法來包含其他兩個視圖。

<%= Html.RenderPartial("MainNav", Model); %> 

<%= Html.RenderPartial("SubNav", Model); %> 

我們有關如何將數據獲取到MainNav & SubNav意見剩餘部分。現在是熟悉ViewModels的好時機。視圖模型只不過是具有某些您想要顯示視圖的屬性的類。

在你的情況下,我會創建3個視圖模型。

  • SiteContentViewModel包含將顯示在您的頁面中的內容。
  • MainNavViewModel包含將顯示在MainNav中的數據。
  • SubNavVIewModel包含將在SubNav中顯示的數據。

然後我會在SiteContentViewModel內包含MainNavViewModel & SubNavVIewModel。

(如果你是確保每一個SiteContent觀都會有MainNav &一個SubNav)

現在是你來填補你需要的是數據的每個視圖模型。

這是代碼的樣子。

public class SiteContentViewModel { 

     public MainNavViewModel MainNav { get; set;} 
     public SubNavVIewModel SubNav { get; set;} 
     // Any Other Data Needed In The SiteContent View (ex. PageTitle) 
} 

public class MainNavViewModel { 
     // Any Data Needed In The MainNav View 
} 


public class SubNavVIewModel { 
     // Any Data Needed In The SubNav View 
} 

現在回到部分視圖,,,使用我們創建的視圖模型,我們可以包含像這樣的部分。

<%= Html.RenderPartial("MainNav", Model.MainNav); %> 

<%= Html.RenderPartial("SubNav", Model.SubNav); %> 

一個重要的事情是讓我們的觀點強烈類型化。類型SiteContentViewModel的

  • SiteContent視圖
  • 型MainNavViewModel的
  • MainNav視圖
  • 型SubNavViewModel

,並在你的SiteContent操作方法,你會做這樣的事情

// Initialize the ViewModels. 
    SiteContentViewModel model = new SiteContentViewModel(); 
    model.MainNav = new MainNavViewModel(); 
    model.SubNav = new SubNavVIewModel(); 

    // Get Data From DB and set the properties that you created in your view models. 
    // examples. 
    model.PageTitle = // some data from db. 
    model.MainNav.(Some Property) = // some data from db. 
    model.SubNav.(Some Property) = // some data from db. 
    return View(model); 
  • SubNav查看

    希望對你有所幫助...瞭解更多信息你可以看到this鏈接

  • +0

    它會可能會更好地使用RenderAction而不是RenderPartial,因爲他在多個視圖中使用它。 – Necros 2010-08-29 14:51:51

    +0

    @Necros ,,,你可能是對的,但RenderAction有一個問題,使我無法使用它,只要我可以。這太慢了! 「根據定義,RenderAction必須運行整個ASP.NET管道來處理系統看來是一個新的HTTP請求,而RenderPartial只是向現有視圖添加額外的內容。」 更多信息在這裏: http://forums.asp.net/p/1502235/3556534.aspx – 2010-08-29 17:54:54

    +0

    它比在多視圖模型中有一個更復雜的屬性要好得多。差別可能是幾微秒,你不會注意到這一點。人們說直接獲取財產與反思獲得財富是一樣的東西......當然,反思速度較慢,但​​除非你做了一百萬次,否則你不會注意到這一點。 – Necros 2010-08-30 03:56:09

    1

    您應該考慮ASP.NET MVC的DDD和TDD。對於它的外觀,你似乎正在使用Linq To Sql。我將嘗試用幾句話來解釋我做了什麼來完成一個好的架構。

    架構

    1. DB語境
    2. 域模型
    3. 庫模式

    這是很好的做法,是不會與你的控制器配合你的數據庫上下文。你想要做的是讓你的控制器調用你的Repository,這反過來會返回你的Model。現在,這裏是棘手的部分,您必須將數據庫上下文對象轉換爲模型對象。

    想象一下,您有一個產品表,Linq To SQL將爲您提供產品類。 產品類是數據庫上下文的一部分,你想要做的是疏遠你的上下文,實際上你的控制器甚至不知道它存在。

    爲什麼我需要一個模型,當我有Linq To SQL?

    對於初學者來說,LTS將在您每次更改數據庫時都會重新生成所有對象,這意味着您將無法更改數據庫上下文。而且你也希望能夠使用ASP。NET MVC 2用於驗證和更多的註釋。

    現在創建一個產品類別爲您的型號

    namespace MvcApplication.Models 
    { 
        public class Product 
        { 
         public int Id { get; set; } 
    
         [Required] 
         [StringLength(10)] 
         public string Name { get; set; } 
    
         [Required] 
         public string Description { get; set; } 
    
         [DisplayName("Price")] 
         [Required] 
         [RegularExpression(@"^\$?\d+(\.(\d{2}))?$")] 
         public decimal UnitPrice { get; set; } 
        } 
    } 
    

    現在你看到這個類是模型的一部分從DB語境完全斷開。現在我們接下來要做的就是創建我們的Repository Class。

    namespace MvcApplication.Repository 
    { 
        public class AppRepository { 
    
         DbContext _context = new DbContext(); 
    
         public IQueryable<Products> GetProducts() 
         { 
          return from p in _context.Products 
            select new Product { 
             Name = p.Name, 
             UnitPrice = p.UnitPrice 
            } 
         } 
        } 
    } 
    

    現在在您的控制器中,您只需調用GetProducts();

    public ActionResult SiteContent(string strSlug) 
    { 
        var repository = new AppRepository(); 
        return View(repository.GetProducts()); 
    } 
    

    漂亮不是它。

    您可以使用AutoMapper將您的數據庫上下文對象映射到您的模型對象。 http://automapper.codeplex.com/