【问题标题】:Web API filtering model propertiesWeb API 过滤模型属性
【发布时间】:2016-05-20 09:39:11
【问题描述】:

对于我的 ASP.NET MVC Web 服务,我有一个模型,我将其作为 JSON 对象返回。现在我的模型中有一些属性我不想返回。

示例模型:

class Account {
    public int ID { get; }
    public string Username { get; }
    public string Password { get; }
    //... more properties
}

假设我只想将 IDUsername 属性作为 JSON 返回。我正在寻找一种仅过滤这些属性的好方法。更改访问修饰符不是我的选择。

我能想到的一个解决方案是创建一个如下所示的白名单。在这里,我添加了一个 DisplayName,能够自定义这是一件好事,但这不是必需的。

class FilterProperty
{
    public string PropertyName { get; }
    public string DisplayName { get; }

    public FilterProperty(string propertyName, string displayName)
    {
        PropertyName = propertyName;
        DisplayName = displayName;
    }
}

class Account
{
    public static FilterProperty[] Whitelist = {
        new FilterProperty("ID", "accountId"),
        new FilterProperty("Username", "accountName")
    };

    //...
}

此解决方案的缺点是:如果我要更改属性的名称,我也需要更改白名单。

我可以完成这项工作还是有更好的解决方案?

【问题讨论】:

  • 查看这篇文章,无论是在发帖还是发帖:odetocode.com/blogs/scott/archive/2012/03/11/…。特别是检查强类型方法,特别是使用接口来限制模型。
  • 你能创建 AccountDto,映射你想要的值,然后返回 AccountDto 而不是 Account?
  • @hellwd 这个我试过了,但是这使我拥有的模型数量增加了一倍,这似乎不是很有效
  • 拥有更多模型并不意味着给您的应用程序增加额外的负担。你如何使用它们是唯一的问题。
  • 只返回一个只包含你想要的属性的匿名对象。

标签: c# asp.net json asp.net-mvc asp.net-web-api


【解决方案1】:

您的问题可能有多种解决方案:

创建一个包含唯一必需属性的 ViewModel,并从原始模型映射这些属性并返回该 viewModel。您可以使用 AutoMapper 库将原始模型映射到您的视图模型。

另外一点是 ASP.NET Web API 使用 Json.Net 作为默认格式化程序,所以如果您的应用程序只使用 JSON 作为数据格式,您可以使用 [JsonIgnore] 忽略属性进行序列化:

class Account {
public int ID { get; }
public string Username { get; }

[JsonIgnore]
public string Password { get; }
//... more properties
}

希望对你有所帮助。

【讨论】:

  • 这是一个很好的将属性列入黑名单的解决方案,但我希望找到一种将它们列入白名单的方法。
【解决方案2】:

Web API 使用 JSON.net 作为默认序列化程序。

您可以添加 JSONIgnore 属性来跳过某个属性。

 public class Class
      {
      // included in JSON
  public string Model { get; set; }
  public DateTime Year { get; set; }
  public List<string> Features { get; set; }

   // ignored
  [JsonIgnore]
  public DateTime LastModified { get; set; }
}

或者,如果您需要忽略大多数属性,您可以使用 opt in 方法。

在您的类上使用 DataContract 属性,然后仅将 Datamember 添加到您想要包含的属性中

[DataContract] 
public class Class
          {
      [DataMember]
      public string Model { get; set; }
      [DataMember]
      public DateTime Year { get; set; }
      // ignored
      public List<string> Features { get; set; }
      public DateTime LastModified { get; set; }
    }

【讨论】:

    【解决方案3】:

    如果您只关心命名,那么使用nameof 运算符是一种选择。 (取决于.NET 版本)

    class Account
    {
        public static FilterProperty[] Whitelist = {
            new FilterProperty(nameof(Account.ID), "accountId"),
            new FilterProperty(nameof(Account.Username), "accountName")
        };
    
        //...
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 2018-10-09
      • 2019-08-23
      • 2020-12-21
      • 2017-05-05
      • 1970-01-01
      • 2019-03-22
      相关资源
      最近更新 更多