我正在创建一个ASP MVC Web API。我现在想要根据正在执行请求的用户确定要对对象进行序列化的属性。 ApiController知道用户。并基于用户,我有一个函数返回一个字符串数组与用户有权在模型上的属性名称。确定要在Json.Net中基于用户序列化的属性
如何将用户传递给ContractResolver,以便它只影响当前的请求,而不会影响其他用户的同时请求?
我正在创建一个ASP MVC Web API。我现在想要根据正在执行请求的用户确定要对对象进行序列化的属性。 ApiController知道用户。并基于用户,我有一个函数返回一个字符串数组与用户有权在模型上的属性名称。确定要在Json.Net中基于用户序列化的属性
如何将用户传递给ContractResolver,以便它只影响当前的请求,而不会影响其他用户的同时请求?
您可以在这个例子中创建一个自定义ContractResolver
var json = JsonConvert.SerializeObject(
new UserClass() {ID=666, Name="john", SurName="doe"},
new JsonSerializerSettings() { ContractResolver = new CustomContractResolver(new[]{"ID", "SurName"}) }
);
,输出JSON将只包括ID
和SurName
(不Name
)
public class UserClass
{
public int ID { set; get; }
public string Name {set; get;}
public string SurName { set; get; }
}
public class CustomContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
IEnumerable<string> _allowedProps = null;
public CustomContractResolver(IEnumerable<string> allowedProps)
{
_allowedProps = allowedProps;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
return _allowedProps.Select(p=>new JsonProperty() {
PropertyName = p,
PropertyType = type.GetProperty(p).PropertyType,
Readable = true,
Writable = true,
ValueProvider = base.CreateMemberValueProvider(type.GetMember(p).First())
}).ToList();
}
}
你不能为你的api收到的每一个请求创建一个新的合约解析器吗?
只要您为每个请求创建一个新实例,合约解析器就永远不会相互冲突。
代码看起来是这样的:
var resolver = new MyUserBasedResolver(userObject);
JsonConvert.SerializeObject(
product,
Formatting.Indented,
new JsonSerializerSettings { ContractResolver = resolver }
);
好的,但你如何在Web API框架中做到这一点?我认为这是真正的问题。 –
此解析器代码看起来不错,但OP正在使用Web API。借助Web API,您可以在应用程序启动时配置解析器,然后稍后发出请求(Web API框架使用解析器处理幕后序列化)。据我了解的问题,允许的属性列表可以根据用户的每个请求更改,所以我认为他正在试图弄清楚他如何能够获得这个列表到解析器为每个不同的请求。 –
@BrianRogers你可能是对的,在这种情况下,可以使用线程静态变量。 '[ThreadStatic]静态IEnumerable allowedProps;' –
@ L.B这正是我所追求的,我要试试这个瞬间:)。 –