2

我正在为 MVC3 使用 MVC 站点地图,但遇到了问题。考虑以下站点地图文件:

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" enableLocalization="true">
  <mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal" Description="Test HOME">
    <mvcSiteMapNode title="Today" controller="Dashboard" action="Today" />
    <mvcSiteMapNode title="Today1" controller="Dashboard" action="Today1" />
    <mvcSiteMapNode title="Today2" controller="Dashboard" action="Today2" />
    <mvcSiteMapNode title="Today3" controller="Dashboard" action="Today3" />
    <mvcSiteMapNode title="Today4" controller="Dashboard" action="Today4" />   
  </mvcSiteMapNode>
</mvcSiteMap>

当我加载我的网页时,我只会得到以下选项:

今天1,今天2,今天3,今天4

但是今天不显示。这是控制器上的一个动作,而其他动作不存在。为什么隐藏控制器上实际存在的项目?我取消了控制器上的授权以排除它与授权有任何关系,但仍然具有相同的效果。

这是站点地图配置(在 web.config 中设置):

  <siteMap defaultProvider="MvcSiteMapProvider" enabled="true">
      <providers>
        <clear />
        <add name="MvcSiteMapProvider" 
             type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" 
             siteMapFile="~/Mvc.Sitemap" 
             securityTrimmingEnabled="true" 
             cacheDuration="5" 
             enableLocalization="true"
             scanAssembliesForSiteMapNodes="false" 
             includeAssembliesForScan="" 
             excludeAssembliesForScan="" 
             attributesToIgnore="visibility" 
             nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider" 
             controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider" 
             actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider" 
             aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider" 
             siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider" 
             siteMapNodeVisibilityProvider="MvcSiteMapProvider.DefaultSiteMapNodeVisibilityProvider, MvcSiteMapProvider" 
             siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider" />
      </providers>      
    </siteMap>
  </system.web>
4

2 回答 2

4

我找出问题所在。HttpContext 用户的 InRole() 方法在库代码中的 MvcSiteMapProvider.DefaultAclModule 中使用。我正在使用表单身份验证,这意味着 InRole 将永远无法工作,因为未设置用户上下文上的角色属性(它不知道如何应用角色)。

我可以编写自己的 aclmodule 提供程序来检查存储在票证中的角色的身份验证票证,或者对于 global.asax 中的每个身份验证请求事件,使用角色集设置上下文。最后我选择了后者:

例如

  if (HttpContext.Current.User != null)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (HttpContext.Current.User.Identity is FormsIdentity)
                {                     
                    FormsIdentity formsId = (FormsIdentity)HttpContext.Current.User.Identity;
                    FormsAuthenticationTicket ticket = formsId.Ticket;

                    // need to do this so MVC sitemap IsInRole works inside default acl module: MvcSiteMapProvider.DefaultAclModule
                    var authData = new AuthenticationModel(ticket.UserData);
                    var roles = new List<string>(authData.EffectiveRoles).ToArray();
                    HttpContext.Current.User = new GenericPrincipal(formsId, roles);
                }
            }
        }
于 2011-05-27T10:14:08.257 回答
1

@jaffa,你的方法帮助了我!!谢谢。在这里,我是如何实现它的。也许它也可以帮助其他人!

public class MenuVisibilityController : Controller, ISiteMapNodeVisibilityProvider
{
    public bool IsVisible(SiteMapNode Node, HttpContext context, IDictionary<string, object> sourceMetadata)
    {
        return context.User.Identity.IsAuthenticated;
    }
}

为 MVC 站点地图实现了可见性提供程序,然后将其用于特定节点的可见性,如下所示:

<mvcSiteMapNode title="Test Menu" controller="Account" action="Index" visibilityProvider="MyProject.Controllers.MenuVisibilityController, MyProject">
  <mvcSiteMapNode title="Test Item 1" controller="Account" action="GetItems" />
</mvcSiteMapNode>

specifying implemented controller in VisibilityProvider should serve the purpose.

于 2013-10-09T06:04:38.483 回答