Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc Can';无法在MvcSiteMap视图中访问ViewData_Asp.net Mvc_Viewdata_Mvcsitemapprovider_Asp.net Mvc 5.1 - Fatal编程技术网

Asp.net mvc Can';无法在MvcSiteMap视图中访问ViewData

Asp.net mvc Can';无法在MvcSiteMap视图中访问ViewData,asp.net-mvc,viewdata,mvcsitemapprovider,asp.net-mvc-5.1,Asp.net Mvc,Viewdata,Mvcsitemapprovider,Asp.net Mvc 5.1,我正在构建一个相当大的MVC项目,我在查看数据时遇到了一些问题。我有一个相当复杂的模型结构。我不想用简单的显示数据“polute”我的模型,但我想要强类型的数据,所以我写了几个简单的类: public class GeneralViewData { private static string Id = "GeneralViewData"; public string PageTitle { get; set; } public bool ShowGuestMenu {

我正在构建一个相当大的MVC项目,我在查看数据时遇到了一些问题。我有一个相当复杂的模型结构。我不想用简单的显示数据“polute”我的模型,但我想要强类型的数据,所以我写了几个简单的类:

public class GeneralViewData
{
    private static string Id = "GeneralViewData";

    public string PageTitle { get; set; }
    public bool ShowGuestMenu { get; set; }
    public string CurrentUserName { get; set; }
    public bool ShowOrganisationAdminMenu { get; set; }

    protected GeneralViewData() { }

    public static GeneralViewData Retrieve(ViewDataDictionary viewDataDictionary)
    {
        object viewData = viewDataDictionary[Id];
        if (viewData == null) return Initiate(viewDataDictionary);
        return (GeneralViewData)viewData;
    }

    private static GeneralViewData Initiate(ViewDataDictionary viewDataDictionary)
    {
        GeneralViewData viewData = new GeneralViewData();
        viewDataDictionary[Id] = viewData;
        return viewData;
    }
}
因此,无论您在何处访问ViewData,都可以轻松获取模型并使用以下工具进行访问:

var generalViewData = GeneralViewData.Retrieve(ViewData);
这在大多数网站上都非常有效,但是我在MVCSiteMapProvider的视图方面遇到了问题。另外,sitemapprovider不传递主视图数据,而是将新数据传递给局部视图

我需要一种方法来让MVCSiteMapProvider将完整的视图数据传递给它的视图,或者通过将GeneralViewData实例存储到其他地方来解决这个问题。我一直在绞尽脑汁想办法解决这个问题,所以我对任何事情都持开放态度。

选项1

您可以使用,但由于您的节点是菜单的一部分,因此您必须在每个控制器操作方法中都这样做

选项2

要使其在全局范围内工作,而不向每个控制器操作添加SiteMapTitleAttribute,还可以在应用程序\u PostAuthorizerRequest事件中显式设置标题

protected void Application_PostAuthorizeRequest(object sender, EventArgs eventArgs)
{
    var user = HttpContext.Current.User;
    if (user.Identity.IsAuthenticated)
    {
        var accountNode = MvcSiteMapProvider.SiteMaps.Current.FindSiteMapNodeFromKey("MyAccount");
        if (accountNode != null)
        {
            accountNode.Title = "Hello, " + user.Identity.Name;
        }
    }
}
这假设您的帐户节点配置了一个值为“MyAccount”的显式密钥集

选项#3

更简洁的方法可能是使用添加一个类,该类可以检索当前用户名和其他属性

如果在上面的Application_PostAuthorizerRequest事件中设置对象,则可能会使用具有静态属性的现有对象

但是,一种更为集成的方法是使用[IDynamicNodeProvider]或IsItemaNodeProvider来提供自定义对象。请注意,如果您这样做,您将需要使用具有从当前请求检索数据(而不是存储数据)的属性/方法的对象,因为此对象将在站点地图的所有用户之间共享

然后,可以自定义MvcSiteMapProvider显示模板,以便在存在自定义对象时在适当的节点上显示此数据

选项4

通过实现和/或如上所述更好地将您的模型与ASP.NET集成,然后您可以将您的配置文件数据添加到自定义IPrincipal和/或IIdentity实现中,以便通过HttpContext对象全局可用

一旦数据在全球范围内可用,您就可以直接从视图中访问它。然后您可以自定义SiteMapNodeModel显示模板,以便在适当的时候显示数据

@model MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
@using System.Web.Mvc.Html
@using MvcSiteMapProvider.Web.Html.Models

@* Fix the title for the MyAccount Node *@
var title = Model.Title;
if (Model.Key == "MyAccount")
{
    title = "Hello, " + (User as CustomPrincipal).CurrentUserName;
}

@if (Model.IsCurrentNode && Model.SourceMetadata["HtmlHelper"].ToString() != "MvcSiteMapProvider.Web.Html.MenuHelper")  { 
    <text>@title</text>
} else if (Model.IsClickable) {
    if (string.IsNullOrEmpty(Model.Description))
    {
        <a href="@Model.Url">@title</a>
    }
    else
    {
        <a href="@Model.Url" title="@Model.Description">@title</a>
    }
} else { 
    <text>@title</text>
}
@model mvcsitemprovider.Web.Html.Models.SiteMapNodeModel
@使用System.Web.Mvc.Html
@使用MvcSiteMapProvider.Web.Html.Models
@*修复MyAccount节点的标题*@
var title=Model.title;
如果(Model.Key==“MyAccount”)
{
title=“Hello,”+(用户作为CustomPrincipal).CurrentUserName;
}
@如果(Model.IsCurrentNode&&Model.SourceMetadata[“HtmlHelper”].ToString()!=“MvcSiteMapProvider.Web.Html.MenuHelper”){
@头衔
}else if(Model.isclick){
if(string.IsNullOrEmpty(Model.Description))
{
}
其他的
{
}
}否则{
@头衔
}
本例假设您已将帐户节点的键属性/属性显式设置为“MyAccount”


我还建议您为“ShowGuestMenu”和“ShowOrganizationAdminMenu”创建一个ASP.NET角色,并结合使用AuthorizeAttribute来控制子菜单的可见性,而不是使用布尔值。如果您希望用户能够打开和关闭菜单,我建议您按照自己的方式进行操作。在这种情况下,我建议使用,而不是通过更改显示模板来控制可见性。

我不确定您为什么需要将数据传递到MvcSiteMapProvider视图,是否调用菜单()在_布局页面中?在本例中,我希望在菜单中显示当前用户名,而不是特定页面(帐户页面)的页面标题。我想完全绕过视图,只需输入一个静态占位符,并使用客户端脚本输入正确的文本,但如果可能的话,我想在服务器端完成。您可以将GeneralViewData类作为属性添加到MenuHelperModel中吗?您可以在构造函数中弹出这些值,它们应该可用于MvcSiteMapHelper模板。我没有尝试过这个,只是一个想法。或者,当用户登录时,将这些值添加到您的身份验证票证/会话中。