C# 基于用户角色的ASP.NET WebAPI条件序列化

C# 基于用户角色的ASP.NET WebAPI条件序列化,c#,nhibernate,serialization,asp.net-web-api,sensitive-data,C#,Nhibernate,Serialization,Asp.net Web Api,Sensitive Data,我有一个映射到POCO的ORM(NHibernate),它将在APIController中返回。我意识到JSON.NET允许我在模型上放置条件序列化方法(ShouldSerialize*);然而,这些模型和它们的方法对它们所处的环境一无所知,它们也不应该知道。我想做的是在登录到我的网站时,根据用户的角色有条件地序列化模型或其一个或多个属性。我可以从概念上理解如何做到这一点,但有一点我迷茫了。以下是一个示例模型: public class SomeModel { public string

我有一个映射到POCO的ORM(NHibernate),它将在APIController中返回。我意识到JSON.NET允许我在模型上放置条件序列化方法(ShouldSerialize*);然而,这些模型和它们的方法对它们所处的环境一无所知,它们也不应该知道。我想做的是在登录到我的网站时,根据用户的角色有条件地序列化模型或其一个或多个属性。我可以从概念上理解如何做到这一点,但有一点我迷茫了。以下是一个示例模型:

public class SomeModel
{
    public string SomeProperty { get; set; }

    [Sensitive]
    public string SomeOtherProperty { get; set; }
}
我希望能够在属性上添加一个属性,将其标记为“敏感”。然后,在我的WebApi中,当它为输出序列化它时,我希望它检查该属性的模型,如果它存在,它应该检查用户的角色。如果用户处于指定的角色中,则序列化程序应序列化该属性,否则它将屏蔽该属性或干脆不序列化该属性。因此,我是否必须编写自己的自定义格式化程序来处理此问题,或者是否有方法连接到内置格式化程序来执行此检查?还是我的思维太局限了,还有其他的方法来处理

我确实认为另一种处理方法是在ORM级别,但在网上找不到好的例子

非常感谢

编辑:我确实在这里发现了另一个类似的问题:
但没有解决办法。另外,我不喜欢通过属性在模型中设置基于角色的访问。我认为这应该在web应用程序中处理。

我提出的一个建议解决方案是让我的ApicController从BaseApiController继承,它覆盖initalize函数,以根据用户的角色设置适当的格式化程序:

protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
{
    base.Initialize(controllerContext);
    // If the user is in a sensitive-data access role
    controllerContext.Configuration.Formatters.Add(/*My Formatter*/);
    // Otherwise use the default ones added in global app_start that defaults to remove sensitive data
}

正如问题中提到的,我提出了我自己的问题“”。我最初确实考虑过使用a,但我相信这会限制您返回什么样的响应。如果希望返回JSON和XML,则需要实现两个格式化程序。要只在一个地方实现过滤器,您需要在堆栈的更高位置实现过滤器

在我的实现中,我希望查找客户机可以访问哪些字段,并从响应中删除客户机不应该看到的任何字段。这与您想要做的非常相似

在senario中,您需要对对象进行反射,并选择包含属性的任何字段,然后将这些值设置为null。如果返回JSON或XML,则如果值为null,则响应中不包括属性,因此您甚至不会泄漏属性名称

例子 下面是一个
DelegatingHandler
的示例实现,它使用反射过滤掉响应对象内容上实现
Sensitive
属性的属性。它假定对象层次是平面的,因此如果有嵌套对象,则需要在对象图中导航,并对层次中的每个对象执行相同的操作

公共类响应的TAFilterHandler:DelegatingHandler
{
受保护的重写System.Threading.Tasks.Task SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
return base.sendaync(请求、取消令牌)
.ContinueWith(任务=>
{
var response=task.Result;
//在此处操作内容
var content=response.content作为ObjectContent;
if(content!=null&&content.Value!=null)
{
过滤器字段(content.Value);
}
返回响应;
});
}
私有空过滤器字段(对象objectToFilter)
{
var属性=objectToFilter
.GetType()
.GetProperties(
BindingFlags.IgnoreCase|
BindingFlags.GetProperty|
BindingFlags.Instance|
(公众),;
foreach(属性中的var propertyInfo)
{
if(propertyInfo.GetCustomAttributes(typeof(SensitiveAttribute),true).Any())
{
propertyInfo.SetValue(objectToFilter,null,新对象[0]);
}
}   
}
}

您可以使用Json.Net中内置的条件序列化。 下面是一篇描述它的文章

也许“ShouldSerialize…”方法可以检查当前主体,您可以从中检查其角色