我在我的网站上制作一个小应用程序,以使用API请求获取用户信息。
[HttpGet("GetUserInfo/{user_id}/{fields?}")]
public IActionResult GetUserInfo(string user_id, params string[] fields)
{
var userProfile = _userManager.GetUserProfile(user_id);
if (userProfile == null)
{
return Ok(null);
}
var userInfo = new
{
id = userProfile.UserId,
email = userProfile.Email,
name = userProfile.Name,
// I don't want to define a null property here:
picture_url = fields.Contains("picture_url") ? "path" : null
};
if (fields.Contains("picture_url"))
{
userInfo.picture_url = "";
}
return Ok(userInfo);
}
当请求有效时,它返回一个JSON对象,默认情况下包含3个属性:id
,email
和name
。
现在,我想检查一下,如果请求想要获得有关此用户的更多信息,就像picture_url
一样。所以,我试过了:
if (fields.Contains("picture_url"))
{
// error in this line
userInfo.picture_url = "path";
}
'< anonymous type:string id,string email,string name>'不包含' picture_url'的定义没有扩展方法' picture_url'接受类型'<匿名类型的第一个参数:字符串id,字符串电子邮件,字符串名称>'可以找到(你错过了使用指令或程序集引用吗?)
如何动态地向匿名对象添加一些属性?
答案 0 :(得分:6)
匿名类型是不可变的,您只能在创建实例时创建和设置属性。这意味着您需要创建所需的确切对象。所以你可以这样做:
if (fields.Contains("picture_url"))
{
return Ok(new
{
id = userProfile.UserId,
email = userProfile.Email,
name = userProfile.Name,
picture_url = "path"
});
}
return Ok(new
{
id = userProfile.UserId,
email = userProfile.Email,
name = userProfile.Name
});
另一种选择是使用Dictionary<string, object>
。例如:
var userInfo = new Dictionary<string, object>
{
{"id", userProfile.UserId},
{"email", userProfile.Email},
{"name", userProfile.Name}
};
if (fields.Contains("picture_url"))
{
// error in this line
userInfo.Add("picture_url", "path");
}
return Ok(userInfo);
此对象将序列化为相同的JSON结构:
{"id":1,"email":"email@somewhere.com","name":"Bob","picture_url":"path"}
答案 1 :(得分:0)
您可以将对象强制转换为动态并添加属性或使用ExpandoObject
类,它基本上是一个属性包(实现为IDictionary<string, object>
)。
var userInfo = new
{
id = userProfile.UserId,
email = userProfile.Email,
name = userProfile.Name
};
dynamic result = userInfo;
if (fields.Contains("picture_url"))
{
result.picture_url = "<your url here>";
// alternatively use expando object
// var expando = (IDictionary<String, Object>)result;
// expando.Add("picture_url", "<your url here>");
// the first parameter is the name of the property
}
return result;
请注意,使用dynamic
关键字或ExpandoObject
会失去强类型和智能感知支持。
但它允许您在最终的json响应中添加或删除属性。
另请参阅我对类似问题Filtering Out Properties in an ASP.NET Core API 的回答。
虽然在使用dynamic
/ ExandoObject
作为用例或类似graphapi的功能时需要小心,但它应该可以正常工作。要删除属性,您只需使用exanod.Remove("PropertyName")
方法。
也可以像
一样轻松实现过滤var dictionaryResult = expando.Where(kv => filter.Contains(kv.Key))
.ToDictionary(kv => kv.Key, kv => kv.Value);
这将删除filter
字符串数组中未定义的所有属性。它适用于任何类型,annonymous
或强类型。