C# 如何在asp.net Web API中筛选出具有自定义属性的字段?

C# 如何在asp.net Web API中筛选出具有自定义属性的字段?,c#,asp.net-web-api,action-filter,C#,Asp.net Web Api,Action Filter,我有一个在我的应用程序中使用的工作模型。我想通过公共API公开其中一些数据,但我有一些字段不想返回供一般使用。 要做到这一点,一个费劲的方法是创建一个单独的模型,然后使用automapper映射我的输出以创建一系列DTO 我想做的是用一个自定义属性注释我的模型,然后在运行时使用某种扩展方法或web API actionfilter在向客户端发送JSON之前过滤掉注释字段。我不能使用JsonIgnore,因为我需要这些字段用于我的应用程序中的操作 有人能给我一个如何做这件事的概述吗 提前谢谢 编辑

我有一个在我的应用程序中使用的工作模型。我想通过公共API公开其中一些数据,但我有一些字段不想返回供一般使用。 要做到这一点,一个费劲的方法是创建一个单独的模型,然后使用automapper映射我的输出以创建一系列DTO

我想做的是用一个自定义属性注释我的模型,然后在运行时使用某种扩展方法或web API actionfilter在向客户端发送JSON之前过滤掉注释字段。我不能使用JsonIgnore,因为我需要这些字段用于我的应用程序中的操作

有人能给我一个如何做这件事的概述吗

提前谢谢

编辑


所以我想我可以使用newtonsoft ShouldSerialize属性,但是我不知道如何找到一种优雅的方式来设置触发该属性的条件。我有一个复杂的模型,我认为在运行时我需要反映整个输出,检测特定命名空间中的任何类,并设置一些值,使ShouldSerialize返回true

,如果您绝对希望避免DTO和
[JsonIgnore]
,并且确实希望使用自定义属性,您可能需要使用一些反射。我将提出一个远不是最佳选择的解决方案,但它可以给你一些想法

首先,创建一个自定义属性来标记不应通过公共API显示的模型属性:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
class DontSendInPublicApiAttribute : Attribute { }
您必须创建一个方法来“擦除”对象属性上不希望显示的数据

public static void RemoveSecretData(object obj)
{
    // Retrieve all public instance properties defined for the object's type and marked with [DontSendInPublicApi]
    var propertiesToHide = obj.GetType()
        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .Where(p => p.GetCustomAttribute<DontSendInPublicApiAttribute>() != null);

    foreach (var prop in propertiesToHide)
    {
        // Set all of these properties in the given object to their default values.
        // VALUE TYPES (ints, chars, doubles, etc.) will be set to default(TheTypeOfValue), by calling Activator.CreateInstance(TheTypeOfValue).
        // REFERENCE TYPES will simply be set to null.
        var propertyType = prop.PropertyType;
        if (propertyType.IsValueType)
            prop.SetValue(obj, Activator.CreateInstance(prop.PropertyType));
        else
            prop.SetValue(obj, null);
    }
}
下面是一个如何称呼它的示例:

var person = new Person() { Name = "John", Age = 29, Occupation = "Engineer", Salary = 200000 };
RemoveSecretData(person);
执行
RemoveSecretData(person)
后,将
person
对象的
occulation
Salary
属性分别设置为
null
0

有关此解决方案的注意事项:

  • 仅适用于属性。如有必要,您必须修改
    RemoveSecretData()
    方法以同时处理字段
  • 不递归访问对象图。如果您的对象引用了另一个具有标记为
    [DontSendInPublicApi]
    的某些属性的对象,则此属性不会被隐藏。如果需要,您必须修改
    RemoveSecretData()
    方法来对更深层次的对象执行递归调用。如果您打算这样做,请注意循环引用
  • 隐藏属性仍将显示在输出JSON上,但值类型的属性将始终显示
    0
    (零)的值,引用类型的属性将始终显示
    null

[JsonIgnore]会帮忙吗?谢谢,这与我的想法一致,但我需要将整个财产移除。我正在考虑只返回一个字典,因为它无论如何都会被序列化为JSON。
var person = new Person() { Name = "John", Age = 29, Occupation = "Engineer", Salary = 200000 };
RemoveSecretData(person);