如果逻辑不那么复杂或更通用,可以设置
custom output formatter
防止某些字段写入响应。
-
-
替换默认序列化。因此,如果在中设置了特定的序列化设置
Startup
,则应转移
让我们看一个例子。
可能有一个自定义属性,比如
public class AuthorizePropertyAttribute : Attribute
{
public AuthorizePropertyAttribute(string role) => Role = role;
public string Role { get; set; }
}
然后输出格式化程序可以如下所示:
public class AuthFormatter : TextOutputFormatter
{
public AuthFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
SupportedEncodings.Add(Encoding.UTF8);
}
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context,
Encoding selectedEncoding)
{
var settings = new JsonSerializerSettings
{
ContractResolver = new AuthorizedPropertyContractResolver(context.HttpContext.User)
};
await context.HttpContext.Response.WriteAsync(
JsonConvert.SerializeObject(context.Object, settings));
}
}
那就需要
public class AuthorizedPropertyContractResolver : DefaultContractResolver
{
public AuthorizedPropertyContractResolver(ClaimsPrincipal user)
{
User = user;
}
public ClaimsPrincipal User { get; }
protected override JsonProperty CreateProperty(MemberInfo member,
MemberSerialization memberSerialization)
{
var result = base.CreateProperty(member, memberSerialization);
result.ShouldSerialize = e =>
{
var role = member.GetCustomAttribute<AuthorizePropertyAttribute>()?.Role;
return string.IsNullOrWhiteSpace(role) ? true : User.IsInRole(role);
};
return result;
}
}
注册:
services.AddMvc(options =>
{
options.OutputFormatters.Insert(0, new AuthFormatter());
});
在这种情况下,简单用户的响应将缺少Salary字段
{"Id":1,"Name":"John"}
同时,经理将看到完整的答复
{"Id":1,"Name":"John","Salary":100000}
,当然属性“Salary”应该设置属性
[AuthorizeProperty("Boss")]
public double Salary { get; set; }