2013-07-02 161 views
12

我剛開始在MVC中工作,我有一個疑問。MVC中公共NonAction方法的用途

而不是Nonaction方法,我們可以在控制器中創建私有方法,或者我們也可以在模型中編寫方法並從控制器調用它。

那麼,在MVC中使用公開NonAction方法的真正目的是什麼?

+0

不確定你在找什麼 - 如果你有方法因爲某些原因需要公開,但不應該是一個行爲,你只需要這樣標記......或者你的問題是「爲什麼人們使用公共方法」? –

+1

@AlexeiLevenkov:是的,我的問題是人們爲什麼使用公共非作用方法。他們甚至可以使用私人方法。 – ChandniShah

回答

6

(我重新調整了答案以更好地解決中註釋的問題)

我認爲,該屬性在這裏只爲更好的靈活性。作爲一名框架設計師,我們希望儘可能放寬最終用戶的編碼限制。沒有公開不採取行動的要求聽起來可能「一般」,但對某些項目可能太嚴格了。添加[NonAction]解決了他們的問題(儘管他們的設計不好),顯然你並不是被迫使用這個屬性,所以從框架設計師的角度來看這是一個雙贏。

另一個原因可能是遺留問題 - 在早期的MVC版本中,只有標記爲[Action]的方法被視爲操作。因此,當他們放寬要求(並且所有公共方法被視爲行動)時,他們保留了[NonAction],以便開發人員不會太困惑。


一般而言,使用NonAction是一種不好的做法 - 這正是你所陳述的理由。如果某件事不應該是一個行動,那麼首先它不應該是public

問題與控制器上的公共非操作方法是,他們讓人們動心實例化控制器並調用該方法,而不是分離出共同的邏輯:

比較

public class MyController : IController 
{ 
    public ActionResult Foo(long orderId) 
    { 
     var order = new OrdersController().GetOrder(orderId); //GetOrder is public 
     ... 
    } 
} 

public class MyController : IController 
{ 
    public ActionResult Foo(long orderId) 
    { 
     var order = _orderService.GetOrder(orderId); 
     ... 
    } 
} 

第一種方法導致控制器與動作中非直接代碼之間的耦合增加。代碼變得難以遵循和重構,並且模擬/測試繁瑣。

除了增加耦合之外,任何公開的非操作方法都是一個安全漏洞 - 如果您忘記標記爲[NonAction](或者更好地遠離公開) - 因爲它被視爲正常操作並且可以在外部調用。我知道最初的問題有點暗示你肯定永遠不會忘記附加屬性如果需要的話,但它也有點重要,要了解如果你願意會發生什麼;)哦,好吧,當我們在這上面,在我看來, 「忘記屬性」在理論上更可能,相比「忘記使方法隱私」。


有時候人們會說有public非行動是必要的單元測試,但同樣的,當自己是不是一個動作就很有可能可以在一個單獨的類被分離並單獨進行測試。此外,即使如果這是不可行的,不管是什麼原因,這標誌着用於測試目的的方法public是一個壞習慣 - 使用internalInternalsVisibleTo被推薦的方式。

+0

非常適合推薦使用private操作,而不是Non Action Method,因爲它可以在函數調用等Action方法的中間操作中使用。現在,他們不能在該控制器之外被調用。到目前爲止非常好。問題 - 爲什麼我應該使用「非動作」方法?你能告訴它的用法的意義嗎? –

+0

_「爲什麼要使用'[NonAction]'」_ - 你不必使用它。我認爲這個屬性是存在的,因爲創建ASP.NET MVC的人想讓這個框架也適用於設計不佳的項目。 – andreister

+0

好的,謝謝。但是,在使用「非行動」方法時,包含哪些不良習慣? –

1

這種情況可能是由需求引起的一些測試框架,比如你需要對該方法進行單元測試,然後你將它公開,雖然它的設計不好但是不能改變這些必須承受它。

默認情況下,MVC框架將控制器類的所有公共方法視爲操作方法。如果您的控制器類包含公共方法並且您不希望它成爲操作方法,則必須使用NonActionAttribute屬性標記該方法。

真正目的使用公共無爲

限制進入非操作方法,以通知的MVC框架,給控制器的方法不動作。

當您嘗試通過URL上的NonAction屬性運行方法時,您會收到錯誤404作爲對請求的響應。

編號:http://msdn.microsoft.com/en-us/library/dd410269%28v=vs.90%29.aspx

查看詳細:http://weblogs.asp.net/gunnarpeipman/archive/2011/04/09/asp-net-mvc-using-nonactionattribute-to-restrict-access-to-public-methods-of-controller.aspx

+1

我知道如何使用NonActionAttribute。我真正的問題是使用Nonaction方法的真正原因。 – ChandniShah

+0

@ChandniShah,當您嘗試通過URL運行帶有'NonAction'屬性的方法時,您會收到錯誤404作爲對請求的響應。 – Satpal

+0

但是,在公共非行動方法的地方,也可以使用私人方法。在這種情況下,我也會得到錯誤。那麼爲什麼我需要使用puble非動作方法? – ChandniShah

0

這是有益的當URL不區分大小寫。這樣,例如,如果您有請求首頁/此去HomeController的關於行動,以及首頁/是去同一個控制器和相同的操作方法。

像下面

public class HomeController:Controller 
{ 
.... 
    public ViewResult About() 
    { 
     return View(); 
    } 

    public ViewResult aBOut() 
    { 
     return View(); 
    } 
} 

框架無法確定哪些about函數來調用,並拋出異常告訴呼叫是模糊的。

enter image description here

當然,解決這個問題的一個辦法是改變動作的名稱。

如果由於某種原因您不想更改操作名稱,並且其中一個函數不是操作,那麼您可以用NonAction屬性修飾此非操作方法。例如:

[NonAction] 
public ActionResult aBOut() 
{ 
    return View(); 
} 
0

我們使用控制器作爲具有自定義ASP管道的綁定驅動程序,每個驅動程序負責渲染結果頁的一個部分(局部視圖)。然後,我們使用的是公共方法,如:

[NonAction] 
publi int GetOrder() 

解決部分訂單頁或其他上解決當前用戶的權限(例如,如果當前部分是編輯還是僅僅只讀)。

所以你不應該限制自己去考慮Controller作爲處理請求的一種方式,而且也可以作爲構建渲染頁面的自定義框架的工具。這樣我們就讓我們的控制器完全負責一項任務,而我們正在分離域的擔憂。

0

默認情況下,MVC框架將控制器類的所有公共方法視爲操作方法。如果您的控制器類包含公共方法,並且您不希望它成爲操作方法,則必須使用NonActionAttribute特性標記該方法。

+0

那麼,在控制器中使用Non Action有什麼優勢? –

+0

對於長時間運行的非CPU綁定請求,您可以使用非操作方法。這可以避免阻止Web服務器在處理請求時執行工作。 – Duk

0

ASP.NET是高度可定製的。假設您將通過重寫MVC HTTP處理程序來更改框架的默認行爲。也許你想根據使用的控制器來定製日誌邏輯。有些控制器使用方法IControllerLogger GetLogger()來實現您的ILoggingController接口。對於這種方法,你需要編寫一個公共的非操作方法。