2009-10-28 111 views

回答

3

對此沒有通用的解決方案,因爲我可以編寫一個自ActionNameSelectorAttribute派生的自定義屬性,並用任何自定義代碼覆蓋,甚至可以將該名稱與隨機GUID進行比較。在這種情況下,您無法知道該屬性將接受哪個操作名稱。

如果你限制你的解決方案,僅考慮方法名稱或內置ActionNameAttribute那麼你就可以反映在類來獲取返回ActionResult的公共方法的所有名稱,並檢查他們是否有ActionNameAttributeName財產覆蓋方法名稱。

+0

你能給我一個簡單的例子嗎? – 2009-10-28 18:42:43

0

使用反射,將是一個非常好的開始。

2

你可以這樣開始:

Type t = typeof(YourControllerType); 
MethodInfo[] mi = t.GetMethods(); 
foreach (MethodInfo m in mi) 
{ 
    if (m.IsPublic) 
     if (typeof(ActionResult).IsAssignableFrom(m.ReturnParameter.ParameterType)) 
      methods = m.Name + Environment.NewLine + methods; 
} 

你必須工作更適合您的需求。

+0

謝謝你爲我舉個例子,它非常有幫助。 – 2009-10-29 09:17:56

8

我一直在琢磨這個問題一段時間了,我相信我已經想出了一個應該在大多數情況下都能正常工作的解決方案。它涉及爲有問題的控制器獲取ControllerDescriptor,然後檢查由ControllerDescriptor.GetCanonicalActions()返回的每個ActionDescriptor

我最終做出了一個在控制器中返回一個局部視圖的操作,但我認爲弄清楚發生了什麼是很容易的,所以請隨時拿出代碼並根據需要進行更改。

[ChildActionOnly] 
public ActionResult Navigation() 
{ 
    // List of links 
    List<string> NavItems = new List<string>(); 

    // Get a descriptor of this controller 
    ReflectedControllerDescriptor controllerDesc = new ReflectedControllerDescriptor(this.GetType()); 

    // Look at each action in the controller 
    foreach (ActionDescriptor action in controllerDesc.GetCanonicalActions()) 
    { 
     bool validAction = true; 

     // Get any attributes (filters) on the action 
     object[] attributes = action.GetCustomAttributes(false); 

     // Look at each attribute 
     foreach (object filter in attributes) 
     { 
      // Can we navigate to the action? 
      if (filter is HttpPostAttribute || filter is ChildActionOnlyAttribute) 
      { 
       validAction = false; 
       break; 
      } 
     } 

     // Add the action to the list if it's "valid" 
     if (validAction) 
      NavItems.Add(action.ActionName); 
    } 

    return PartialView(NavItems); 
} 

可能有更多的過濾器需要尋找,但現在這適合我的需要。

相關問題