2010-10-05 56 views
8

我有以下情形:我的網站顯示文章(由管理員輸入,如博客)。ASP.NET MVC控制器參數可選(即Index(int?id))

因此,要查看文章,用戶將被引用到主頁/文章/ {文章ID}。

但是,用戶使用jsTree列表選擇要從Articles.aspx視圖中查看自己的文章。

所以我需要做的是能夠區分兩種情況:用戶訪問特定文章,或者他只是試圖訪問「主」文章頁面。我嘗試將「Articles」控制器參數設置爲可選(int?id),但是在使用控制器內的id值時遇到問題。

處理這種情況的最佳方式是什麼?也許我只需要一個更好的邏輯來檢查在「url」中是否提供了id參數?

我想避免使用兩個視圖/控制器,只是出於代碼重複的原因。

回答

13

使用單獨的操作,如:

public ActionResult Articles() ... 
public ActionResult Article(int id) ... 

或者將其移動到一個文章控制器(使用默認路由的網址是:ArticlesArticles/Detail/{id}):

public class ArticlesController : Controller 
{ 
    public ActionResult Index() ... 
    public ActionResult Detail(int id) ... 
} 

如果仍然必須使用它像你發佈的,嘗試其中的一種:

public ActionResult Articles(int id = 0) 
{ 
    if(id == 0) { 
     return View(GetArticlesSummaries()); 
    } 
    return View("Article", GetArticle(id)); 
} 
public ActionResult Articles(int? id) 
{ 
    if(id == null) { 
     return View(GetArticlesSummaries()); 
    } 
    return View("Article", GetArticle(id.Value)); 
} 
+0

」或者將其移動到Articles控制器(使用默認路徑的網址將是:Articles and Articles/Detail/{id}):「 這可能是最好的方法。謝謝! – 2010-10-05 17:28:26

0

設置所需參數,然後在路由中設置一個默認值,該值不是有效索引,並且表明您的操作應該呈現主頁面頁面。

1

這對我來說聽起來像兩個單獨的頁面,應該這樣對待。您有「主」視圖頁面和「文章」頁面。

我會把它分成兩個動作。他們不應該真的有太多的重複,都應該做一個調用來獲得相同的ModelView,文章將簡單地得到一個擴展!

5

定義,你知道ID的默認值是表示沒有提供值的 - 通常所有的0

public ActionResult Articles([DefaultValue(0)]int Id) 
{ 
    if (Id == 0) 
    // show all 
    else 
    // show selected 
.. 
+0

謝謝,這正是我所需要的。 – 2010-10-05 13:39:09

+1

使用DefaultValue屬性看起來像是一個非常混亂的方式來解決這個問題。 – Ryan 2010-10-05 13:45:24

+0

嗯......也許我會使用2個視圖畢竟。我需要主要的介紹性文章頁面更加「有趣」HTML明智。 – 2010-10-05 14:01:37

7

首先,我同意@Steve :)。但是,如果你真的想用

int? id 

,你可以查一下你的控制器的方法如果ID使用簡單

if(id == null) 

如果是這樣,加載從數據庫中的所有物品(或東西設置並且將這些傳遞給您的視圖(直接或通過使用視圖模型)。如果設置了id,只需從數據庫中加載具有該id的文章並將其發送到視圖(如果不使用視圖模型,則可能在列表中)。

在您的視圖中,只是加載列表中的所有文章與提供給視圖的文章。其中包含全部或僅包含一個。

完全啞代碼

public ActionResult showArticles(int? id){ 
    List<Articles> aList; 
    if(id == null){ 
     aList = repository.GetAllArticles().ToList(); 
    }else{ 
     aList = new List<Articles>(); 
     aList.add(repository.GetArticleByID(id)); 
    } 

    return View(aList); 
} 

你的觀點有類似:

<% Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<List<Articles>>"%> 

foreach(Articles a in Model) 
    //display article 

而且你怎麼稱呼它使用接下來的兩個選項之一:

html.ActionLink("one article","showArticles","Articles",new {id = aID},null} 

html.ActionLink("all articles","showArticles","Articles"} 
2

最簡單的解決方法是有兩種不同的行爲和觀點,但是將相同的行動命名。

public ViewResult Articles() 
{ 
    //get main page view model 
    return View("MainPage", model); 
} 

public ViewResult Articles(int id) 
{ 
    // get article view model 
    return View(model); 
} 
+1

好了,但是當我嘗試使用調用主文章頁面: <%= Html.ActionLink(「公司章程」,「公司章程」,「家庭」)%> 我得到一個錯誤: 的當前請求操作'文章'控制器類型'HomeController'在以下操作方法之間不明確: System.Web.Mvc.ActionResult文章()類型dr_teman_MVC.Controllers.HomeController System.Web.Mvc.ActionResult文章(Int32)on鍵入dr_teman_MVC.Controllers.HomeController – 2010-10-05 14:04:08

+0

您的(默認)路由是否指定默認ID?我想這可能是一個問題。我可能會命名一個動作文章和其他文章。「 – Ryan 2010-10-05 14:54:09

0

好了,這是我使用的聯合解決方案:

使用相同的控制器,以默認值:

public ActionResult Articles([DefaultValue(0)]int id) 

如果使用DefaultValue,我指的是 「MainArticles」 的看法。如果提供了文章ID - 我參考了「文章」視圖以及在ViewModel中傳遞的相應文章。

在這兩種情況下,ViewModel都會填充數據兩種視圖需要(完整的文章和類別列表)。

感謝大家的幫助!

0

我不知道,如果你想這一點,而是如果你是直接鍵入值的URL,然後,而不是通過這樣的:

controller/action/idValue

試圖傳遞這樣的:

controller/action?id=value