通过ViewBag评估来自web.config文件的值

时间:2013-08-08 15:56:39

标签: c# asp.net-mvc razor

任务很简单。我在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 个答案:

答案 0 :(得分:1)

控制器

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

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

@if (ViewBag.MenuTypes.Contains("3"))
{
     <li><a class="Trucks" href="#3">Trucks</a></li>
}

答案 1 :(得分: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. 更难以维护,因为您没有在配置之上使用动态分层,可能存在也可能不存在。
  5. 我希望这会有所帮助。

答案 2 :(得分:0)

您有更多可能以更加可控的方式更好地解决此问题。

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

通过这种方式,您可以对ViewBag进行更多控制和行为设置。

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

OOrrr,如果只在一个动作上需要它,那么最好是在那里简化和设置ViewBag。

答案 3 :(得分: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>

您如何看待这种方法?