【问题标题】:How to hide a Model class field based on custom logic in MVC Web Api RC如何在 MVC Web Api RC 中隐藏基于自定义逻辑的模型类字段
【发布时间】:2016-07-15 04:35:57
【问题描述】:

我正在使用 Asp.Net Mvc Web api RC。

我想使用自定义属性隐藏模型类的字段/属性。下面是我的课:

public class Employee
{              
     public int EmpId { get; set; }       
     public string Name{ get; set; }

     //Wanted to hide this attribute based on custom logic. Like for a certain role, i want to hide the designation
     public string Designation{ get; set; }

     public string Department{ get; set; }
}

我们如何使用数据注释来实现。我的意思是我想创建一个单独的属性以这种方式使用:

[HideForRoles(Roles="Admin,Writer")]
public string Designation{ get; set; }

更新:

因为我正在开发 web api。响应被序列化为 XML 或 Json 格式,具体取决于格式化程序。所以更好的问题是如何在写入响应时不允许字段被序列化。

但是,一种选择可能是使用 IgnoreDataMember 属性。喜欢

[IgnoreDataMember]
public string Designation{ get; set; }

但上面是一个编译时声明,我不能强加任何条件。

问题:如何在运行时根据某些条件进行序列化时忽略字段/属性?

【问题讨论】:

    标签: asp.net-mvc-4 asp.net-web-api


    【解决方案1】:

    在第一次使用 Web Api 时完全错过了,我深表歉意。

    您要做的是创建一个自定义格式化程序。

    这里有一篇关于 MVC 和 Web Api 之间的流程/差异的好文章(我知道你已经理解了,这里仍然有一些有效的观点): http://lostechies.com/jimmybogard/2012/04/10/asp-net-web-api-mvc-viewmodels-and-formatters/

    这是自定义格式化程序的示例实现: http://www.tugberkugurlu.com/archive/creating-custom-csvmediatypeformatter-in-asp-net-web-api-for-comma-separated-values-csv-format

    在此基础上,您将使用反射来读取属性,在您必须编写的自定义 ActionFilterAttribute 的基础上构建,您可以在其中评估用户的角色并确定应该省略/包含哪些字段。这是一个动作过滤器的示例: https://github.com/MisterJames/MovieFu/blob/master/MovieFu/ActionFilters/UserNameFilter.cs

    希望这会有所帮助。

    干杯。

    【讨论】:

    • 自定义格式化程序是在 Wb api 中弥合模型和响应之间差距的方式。我认为 MVC4 Web api 中缺少某些/某些层。这在 MVC 中以“视图”的形式存在。我将在不久的将来尝试编写自定义格式化程序。但是 Web api 附带的默认 json 和 xml 格式化程序存在不同的障碍。我们必须完全忽略它们并将我们自己的位置包括在内。嗯……想……
    【解决方案2】:

    最好的办法是返回一个dynamic 对象。在这种情况下,您可以说:

            dynamic viewModel = new ExpandoObject();
            viewModel.Id = 12;
            if(role == "Admin")
            {
                viewModel.SecureStuff = "Others should not see it";
            }
    

    【讨论】:

    • 这会起作用,但此时角色在他的序列化中变得硬编码,我认为他试图避免这种情况。我认为带有一些自定义操作过滤器属性的序列化程序会成为一个很好的 NuGet 包。
    • @MisterJames 这只是一个示例。无论如何,使用基于角色的安全性也是硬编码。
    • 完全同意,这正是您希望它生活的地方。如果我使用它,我希望角色魔术字符串存在于序列化程序之外。
    • 是的,我已经按照阿里建议的方式实现了,但使用了反射。为不想显示的字段设置 null 只是一件简单的事情。但是它将以 XML 响应格式显示,但以 json 格式隐藏。我在下面的答案中给出的示例代码。
    【解决方案3】:

    它不会那么简单,因为您需要有条件地在视图中呈现字段。但是你可以通过属性获得大部分的方式。

    您需要让您的自定义属性元数据感知,然后检查您的视图中的属性。解决方案在这里发布:Can't get Custom Attribute Value in MVC3 HTML Helper

    干杯。

    【讨论】:

    • 对我来说没有“视图”:( 因为我使用的是 MVC4 Web Api,所以有基于格式化程序的请求和响应。但你的对其他开发人员会有用。
    【解决方案4】:

    我已经在模型存储库中完成了授权检查。比较理想的方法是创建自定义格式化程序,以根据某些条件隐藏某些字段。

    在从 db 获取员工列表并将它们放入列表后,我再次迭代并将 NULL 放置到我不想显示的字段中。 我写的代码是:

    foreach (var employee in listEmployees)
    {
         //get all props. of Employees object using reflection
         var props = employee .GetType().GetProperties();
    
         //loop through each field to match with the field name to remove/place null
         foreach (var propertyInfo in props)
         {
              var fieldName = propertyInfo.Name;
              if (fieldsNamesToRemove .Contains(fieldName))
              {
                        propertyInfo.SetValue(employee , null, null);
              }
         }
     }
    

    这里的 fieldsNamesToRemove 是我根据当前用户的角色动态创建的列表。

    这个解决方案实际上为我们不想显示的字段设置了一个 NULL。因此,在 JSON 格式中,字段不显示,但在 XML 中,字段以类似 lt; 的语法显示。指定 i:nil="true"/ gt;,但易于管理,因为我们主要需要处理 json 响应。

    感谢 Ali 和 MisterJames 提出的宝贵建议

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-30
      • 2011-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      相关资源
      最近更新 更多