在C#/.Net 6中,如何从响应中动态地包含/排除属性



我希望允许用户为响应确定一些可选字段。这里的示例是简单的字符串,但在实际示例中,它可以用于显示/不显示数百甚至数千行复杂属性。

说我有一个班级

public class MyClass
{
public string Foo { get; set; }
public string Bar { get; set; } 
public string Baz { get; set; }
}
//By default, I only want to return Foo
//Ex. 1
// GET /myclass
//Returns
{
Foo = "Hello Foo"
} 

但是,我想让用户决定是否包括Bar和Baz。用户可以进行

//Ex. 2
// GET /myclass?includeFoo=true&includeBar=true
//Returns 
{
Foo = "Hello Foo",
Bar = "Hello Bar",
Baz = "Hello Baz"
}

或者用户可以只包括一个酒吧或baz

//Ex 3
// GET /myclass?includeBar=true
//Returns
{
Foo = "Hello Foo",
Bar = "Hello Bar"
}

我知道我可以使用动态对象类型来实现这个目标,但有没有一种方法可以在不使用动态对象的情况下做到这一点?

假设您已经处理了传入查询字符串的处理,以确定包含的属性集,那么您可以正常构建响应,然后对其进行一些最终处理,以从用户没有要求的最终响应中删除字段。

使用JSON.NET,您可以串行化此";脂肪;response对象转换为JSON并将其加载到CCD_ 2中。从那里,您可以使用Remove方法从不想发回的响应中删除属性。

类似这样的东西:

//Process the query string into a set of included properties
var propsToInclude = new HashSet<string>().
...
//Serialise into a JObject
var response = new MyClass { .... }
var obj = JObject.Parse(JsonConvert.SerializeObject(response));
//For each property on MyClass, if that property's name is not in the included
//set, remove it from the serialised response 
foreach(var prop in typeof(MyClass).GetProperties())
{
if(!propsToInclude.Contains(prop.PropertyName))
obj.Remove(prop.Name);
}
//Send back the stripped-down JSON response
return obj.ToString();

从那时起,将其提取到一个助手方法中并不是一个巨大的飞跃,该方法接受一个类型、该类型的实例、一组要包含的属性,并返回只包含请求属性的JSON:

public class MyClass
{
public string Foo { get; set; }
public string Bar { get; set; }
public string Baz { get; set; }
}
public string SerialiseObject<T>(T obj, HashSet<string> propsToInclude)
{
var response = JObject.Parse(JsonConvert.SerializeObject(obj));
foreach(var prop in typeof(T).GetProperties())
{
if (!propsToInclude.Contains(prop.Name))
response.Remove(prop.Name);
}
return response.ToString();
}
var x = new MyClass { Foo = "foo", Bar = "bar", Baz = "baz" };
//{ "Foo": "foo" }
var y = SerialiseObject(x, new HashSet<string> { nameof(MyClass.Foo) });
//{ "Bar": "bar", "Baz": "baz" }
var z = SerialiseObject(x, new HashSet<string> { nameof(MyClass.Bar), nameof(MyClass.Baz) });

正如@Serge所指出的,你可以使用null技巧并忽略数据,你也可以使用(System.Text.Json(JsonExtensionDataAttribute或(Newtonsoft(JsonExtensionsDataAttribute

public class MyClass
{   
public string Baz { get; set; }
[JsonExtensionData]
public Dictionary<string, object> ExtraProperties { get; set; }
}

您可以通过配置序列化程序来实现这一点。如果您使用的是System.Text.Json,请参阅此处了解详细信息:https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-ignore-properties?pivots=dotnet-6-0#忽略所有空值属性

如果您使用Newtonsoft.Json,那么配置应该类似,但它被称为NullValueHandling,请参阅此处了解详细信息:https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm

相关内容

  • 没有找到相关文章

最新更新