2

任务很简单。我在 web.config 中有价值,如下所示:

 <add key="MenuTypes" value="1,2,3"/>

在 Razor 文件中,我需要根据这些值渲染一些菜单。因此,如果我在配置文件(MenuTypes)中有值 3,我想渲染该项目。如果我没有它,我不想渲染它:

<div>  
            <ul id="setThemUp" class="vehicles">  
                <li><a class="bikes" href="#1">Bikes</a></li>  
                <li><a class="cars" href="#2">Cars</a></li>
                @if (ViewBag.MenuTypes(((int)3).ToString()) > -1)
                {
                   <li><a class="Trucks" href="#3">Trucks</a></li>
               }

            </ul>

我也试过:

 <div>  
            <ul id="setThemUp" class="vehicles">  
                <li><a class="bikes" href="#1">Bikes</a></li>  
                <li><a class="cars" href="#2">Cars</a></li>
                @if (ViewBag.MenuTypes.Contains("3"))
                {
                   <li><a class="Trucks" href="#3">Trucks</a></li>
               }

            </ul>
</div>

但在这两种情况下,我都得到:用户代码未处理 RunTimeBinderException 无法对空引用执行运行时绑定。

我让它像这样工作:

<add key="TrucksEnabled" value="true"/>

<div>  
            <ul id="setThemUp" class="tabs">  
                <li><a class="bikes" href="#1">Bikes</a></li>  
                <li><a class="cars" href="#2">Cars</a></li>
                @if ((bool)ViewBag.TrucksEnabled)
                {
                   <li><a class="Trucks" href="#3">Trucks</a></li>
               }

            </ul>
</div>

但我不能以这种方式使用它。我需要它像第一个例子一样工作。我对 Razor/MVC 不是很好。任何帮助表示赞赏。

4

4 回答 4

1

我个人认为你可能从错误的角度来处理这个问题,即视图主导的逻辑而不是业务逻辑。你希望你的观点对这一切一无所知,真的。我建议创建某种存储,例如枚举:

    public enum MenuType
    {
        Cars = 1,
        Trucks = 3
    }

然后有一个像这样的静态方法:

public static class MenuFunctions
{
    public static bool ShowMenu(MenuType menuType)
    {
        bool showMenu = false;
        string appSetting = ConfigurationManager.AppSettings["YourKey"];
        if (!String.IsNullOrEmpty(appSetting))
            showMenu = appSetting.Contains("/" + (int)menuType.ToString() + "/");

        return showMenu;
    }

}

你的剃须刀用法是:

@if(MenuFunctions.ShowMenu(MenuType.Trucks)
{
    //do truck menu
}

您的应用程序设置如下:

<add key = "YourKey" value = "/1/2/3/" />

或者使用您决定的任何分隔符。您可以将项目拆分为一个数组,然后拆分为一个 int,以便在静态函数中进行更准确的比较,但您明白我的意思。

这种方法的好处:

  1. 你的观点对逻辑一无所知。
  2. 如果你将它包装在一个 try 块中,它将优雅地失败服务器端,你可以在适当的地方捕获和记录异常,而不是让你的视图爆炸。
  3. 您在设计时使用 Enum 处理集合类型。拿出一个菜单,你会在构建时知道你出错的地方,而不是在运行时的 QA 或更糟。
  4. 更易于维护,因为您没有使用位于可能存在或不存在的配置之上的 Dynamics。

我希望这有帮助。

于 2013-08-08T16:46:11.907 回答
1

控制器

var menuTypes = WebConfigurationManager.AppSettings["MenuTypes"].ToString())
string[] tokens = menuTypes.Split(','); //Convert the strings into an array
ViewBag.MenuTypes = tokens;

View --MenuTypes现在是一个列表,因此您现在可以使用Contains()

@if (ViewBag.MenuTypes.Contains("3"))
{
     <li><a class="Trucks" href="#3">Trucks</a></li>
}
于 2013-08-08T16:22:25.813 回答
0

伙计们,所有的例子都很棒,向我展示了很好的学习材料和选择。在仔细查看您提供的示例后,我找到了另一个我打算使用的解决方案。这很简单:

<div>  
            <ul id="setThemUp" class="Vehicles">  
                <li><a class="bikes" href="#1">Bikes</a></li>  
                <li><a class="cars" href="#2">Cars</a></li>
                @{string options = System.Configuration.ConfigurationManager.AppSettings["MenuTypes"];

                  if (options.IndexOf("3") > -1) 
                 {
                   <li><a class="trucks" href="#3">Trucks</a></li>
                 }
                }
            </ul>
 </div>

您如何看待这种方法?

于 2013-08-09T07:51:51.337 回答
0

你有更多的可能性来更好地解决这个问题,也许是以一种更可控的方式。

您可以创建一个 ActionFilter 并装饰主控制器(或您需要此属性的其他控制器)以读取应用程序密钥(如WebConfigurationManager.AppSettings["PFUserName"].ToString()

这样您就可以对 ViewBag 进行更多控制和行为设置。

另一种解决方案是,如果你有一个 baseController,你可以设置一个属性来读取这个应用程序的 Key,尽管只有在你的整个应用程序中需要。

OOrrr,如果您只需要一个动作,那么最好的办法是简化并在那里设置 ViewBag。

于 2013-08-08T16:12:03.593 回答