2015-07-20 56 views
0

我正在爲我的ASP MVC 5項目使用MvcSitemapProvider。MvcSitemapProvider在使用currentNode時拋出溢出異常

我已經實現了一個自定義授權,以檢查來自站點地圖的角色是否與用戶角色相同。

這是什麼樣子:

public class CustomAuthorize : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     bool authorize = false; 

     var roles = SiteMaps.Current.CurrentNode.Roles; 
     foreach (var role in roles) 
      if (System.Web.Security.Roles.IsUserInRole(role)) 
       authorize = true; 

     return authorize; 
    } 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     filterContext.Result = new HttpUnauthorizedResult(); 
    } 
} 

我的問題是,使用SiteMaps.Current.CurrentNode.Roles時,它拋出一個An unhandled exception of type 'System.StackOverflowException' occurred in System.Web.dll,我不知道爲什麼。對象被填充,沒有任何內容爲空。

爲什麼會發生這種情況?現在,我茫然不知如何得到這個工作作爲一個簡單的currentNode不工作...

+0

當你正在調試時,它會到達每個循環還是在之前引發的異常? – Casey

+0

它是在currentNode方法中引發的,它是一個mvcsitemapprovider方法。這就是爲什麼我無能爲力,因爲我無法影響它,也不知道它爲什麼會被拋出。 – Rovdjuret

回答

1

AuthorizeAttribute默認實現所有你需要用MvcSiteMapProvider互動。 AuthorizeAttribute已經支持角色。

// Only users in the "Manager" role have access to all actions on this controller 
[Authorize(Roles = "Manager")] 
public class AccountController : Controller 
{ 
    public ActionResult Manage() 
    { 
     return View(); 
    } 

    public ActionResult ChangePassword() 
    { 
     return View(); 
    } 
} 

您唯一需要做的就是啓用安全修整。請參閱security trimming文檔。

+0

感謝您的反饋。我知道我可以像你一樣使用它,但我希望它依賴於站點地圖,因爲我想在運行時更改它。控制器被編譯並且無法更改...這就是爲什麼我想要在當前節點獲取站點地圖角色並檢查用戶是否具有這些角色。 還有別的辦法嗎? – Rovdjuret

+1

您不能將角色集合用於此目的。 SiteMap被緩存並且爲所有用戶共享,並且不可能在運行時動態地改變角色。您應該尋找另一種方法來定義這種動態行爲,但是您通過對AuthorizeAttribute進行子類化來使用正確的方法,因此它只需要在一個地方定義。看看MVC 5的說法。 – NightOwl888

1

我想調用當前節點生成,這將再次調用您的授權過濾器的頁面另一個請求。換句話說,這段代碼創建了一個無限循環的調用本身,其中沒有一個會返回,這就是調用堆棧溢出的原因。

我會以另一種方式存儲您想檢查的角色。

+0

最有可能!我想我將不得不使用acl模塊並跳過自定義屬性。 – Rovdjuret