您可以使用自定义合同解析器自行实现。假设你有属性:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class JsonViewAttribute : Attribute {
public JsonViewAttribute(string viewName) {
ViewName = viewName;
}
public string ViewName { get; }
}
观看次数:
public static class JsonViews {
public const string Administrator = "Administrator";
}
还有 DTO 类:
public class UserDto
{
public int ID { get; set; }
public String Name { get; set; }
[JsonView(JsonViews.Administrator)]
public DateTime DateOfBirth { get; set; }
[JsonView(JsonViews.Administrator)]
public string Email { get; set; }
}
您的目标是仅在当前用户经过身份验证并具有目标角色(“管理员”)的情况下序列化带有JsonView 修饰的属性。然后你可以像这样创建合约解析器:
public class JsonViewContractResolver : JsonContractResolver {
public JsonViewContractResolver(MediaTypeFormatter formatter) : base(formatter) {
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
JsonProperty property = base.CreateProperty(member, memberSerialization);
var viewAttr = member.GetCustomAttribute<JsonViewAttribute>();
if (viewAttr != null) {
// if decorated with attribute
property.ShouldSerialize = (instance) => {
var context = HttpContext.Current;
if (context == null)
return true;
// we are in context of http request
if (context.User == null || context.User.Identity == null)
return false;
// should serialize only if user is in target role
return context.User.Identity.IsAuthenticated && context.User.IsInRole(viewAttr.ViewName);
};
}
return property;
}
}
并在配置中设置:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new JsonViewContractResolver(config.Formatters.JsonFormatter);
}
现在每当你像这样在控制器中返回 json 时:
[System.Web.Http.HttpGet]
public UserDto Get()
{
return new UserDto()
{
ID = 1,
DateOfBirth = DateTime.UtcNow,
Email = "test",
Name = "name"
};
}
并且它被序列化为 json - 如果用户不是管理员,则管理属性将被省略。
请注意,如果您这样做:
[System.Web.Http.HttpGet]
public IHttpActionResult Get()
{
return Json(new UserDto()
{
ID = 1,
DateOfBirth = DateTime.UtcNow,
Email = "test",
Name = "name"
});
}
不使用格式化程序,您必须自己使用自定义格式化程序传递序列化设置(当然您需要将其变成可重用的方法,例如在您的基本控制器中声明 Json 方法,所有其他方法都从该方法继承):
return Json(new UserDto()
{
ID = 1,
DateOfBirth = DateTime.UtcNow,
Email = "test",
Name = "name"
}, GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings);
使用角色只是一个示例,展示了如何扩展 asp.net api 默认使用的 JSON.NET 序列化程序以实现所需的结果。