C# 根据用户访问级别自动生成SelectList

C# 根据用户访问级别自动生成SelectList,c#,asp.net-mvc,C#,Asp.net Mvc,我已经实现了一个访问级别系统,可以防止/允许访问不同的文档类型 我有几个索引页,可以列出多种类型的文件。这些可以使用dropdownlist进行过滤 我想不出一种方法可以自动适当地绑定dropdownlist,这样它就不会显示当前用户无权访问的文档 是否有一些自定义模型绑定/泛型/html帮助器魔法可以帮助我,还是我太完美主义了 我的自动取款机代码: ViewBag.DocumentTypesList = new SelectList( new Dictionary

我已经实现了一个访问级别系统,可以防止/允许访问不同的文档类型

我有几个索引页,可以列出多种类型的文件。这些可以使用dropdownlist进行过滤

我想不出一种方法可以自动适当地绑定dropdownlist,这样它就不会显示当前用户无权访问的文档

是否有一些自定义模型绑定/泛型/html帮助器魔法可以帮助我,还是我太完美主义了

我的自动取款机代码:

ViewBag.DocumentTypesList = new SelectList(
               new Dictionary<DocumentTypeForUI, string>
                            {
                                { DocumentTypeForUI.Invoice, DocumentType.Invoice.Localize() },
                                { DocumentTypeForUI.CreditNote, DocumentType.CreditNote.Localize() },
                            },
               "Key",
               "Value",
               ViewBag.Type);

您已经得到了答案:只需使用名为“GenerateSelectListFor”的方法将“Magic”变成一个静态类。然后,在视图中,完全跳过ViewBag。视图可以与命名空间中的任何公共类进行对话

namespace YourNameSpace
{

    public static class Magic
    {
        public static SelectList GenerateASelectListFor()
        {
            // your code here obviously....
            return new SelectList(new Dictionary<string, string> { { "Foo", "Barr" }, { "Car", "Dog" } });
        }
    }
}
您只需确保
视图
文件夹根目录中的
Web.config
(不是主Web.config)中有一个名称空间条目:

<namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
    <add namespace="YourNameSpace"/>
</namespaces>


顺便说一句,您应该考虑放弃整个ViewBag/ViewData范式,转而支持针对ViewModels的强类型视图,后者是专门为从业务层到每个视图获取所需内容而创建的类。它们消除了ViewBag的使用问题,ViewBag的工作原理类似于会话/Cookie/等,在会话/Cookie/等中,您需要记住通过字符串名称向其中抛出的对象/类型。因为ViewModels看起来就像普通类,所以您可以将所有普通类型的继承应用于它们,以增强您在这个问题中所需要的可重用性


例如,如果应用程序给定部分中的每个页面/视图都需要上述过滤的选择列表,那么您可以让所有这些视图模型从实现过滤的基础继承,并拥有一个
public SelectList DocumentTypeChoices{get;set;}
prop,您可以在其中输入一次逻辑。只是一个建议

这根本不应该由你的MVC应用程序来处理——按权限进行过滤应该在业务逻辑/服务层。这样你的MVC应用程序就可以显示它得到的任何东西。正确。我正在尝试将其转移到业务逻辑。这个问题实际上是关于如何做到这一点,并以可重用的方式将该逻辑应用于UI元素。非常有趣。我想我应该使用一个扩展函数。这样行吗?public static MvcHtmlString MagicDropDownListFor(此HtmlHelper HtmlHelper、表达式表达式、IEnumerable selectList、对象htmlAttributes、用户currentUser){…}我更喜欢让我的
HtmlHelper
扩展不太特定于应用程序,这样我就可以将库放到下一个项目中,但如果你的应用程序中有一致的模式,你当然可以这样做。
namespace YourNameSpace
{

    public static class Magic
    {
        public static SelectList GenerateASelectListFor()
        {
            // your code here obviously....
            return new SelectList(new Dictionary<string, string> { { "Foo", "Barr" }, { "Car", "Dog" } });
        }
    }
}
@Html.DropDownList("Foo", YourNameSpace.Magic.GenerateASelectListFor())
<namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
    <add namespace="YourNameSpace"/>
</namespaces>