问题描述
我后被返回给客户端,可以让我修改对象的JSON泛型方法,尤其是去除返回的对象的某些属性。类似于建议。
I'm after a generic method that allows me to modify the JSON of an object being returned to the client, specifically the removal of certain properties in returned objects. Similar to what is suggested here.
的修改是非确定性在于它们每个请求的决定的基础上,与用户相关联的规则。因此,这不适合于被缓存的方法。
The modifications are non-deterministic in that they are determined per-request, based on rules associated with the user. So this not suited to a method that is cached.
我查看了几种方法。最明显的选择将是一个JsonConverter,但有这个问题,因为上市。如果转换器被直接加到一个类或属性与,比如说,
Note this only works when the converter is included in JsonSerializerSettings.Converters
. If the converter is applied directly to a class or property with, say,
[JsonConverter(typeof(TestConverter<Inua.WebApi.Authentication.IUser>))]
那么仍然会发生无限递归,因为 CanConvert
不要求直接应用转换器。
Then infinite recursion will still occur since CanConvert
is not called for directly applied converters.
因此:
public class TestConverter<TBaseType> : JsonConverter
{
[ThreadStatic]
static Stack<Type> typeStack;
static Stack<Type> TypeStack { get { return typeStack = (typeStack ?? new Stack<Type>()); } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JToken token;
using (TypeStack.PushUsing(value.GetType()))
{
token = JToken.FromObject(value, serializer);
}
// in practice this would be obtained dynamically
string[] omit = new string[] { "Name" };
JObject jObject = token as JObject;
foreach (JProperty property in jObject.Properties().Where(p => omit.Contains(p.Name, StringComparer.OrdinalIgnoreCase)).ToList())
{
property.Remove();
}
token.WriteTo(writer);
}
public override bool CanConvert(Type objectType)
{
if (typeof(TBaseType).IsAssignableFrom(objectType))
{
return TypeStack.PeekOrDefault() != objectType;
}
return false;
}
public override bool CanRead { get { return false; } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public static class StackExtensions
{
public struct PushValue<T> : IDisposable
{
readonly Stack<T> stack;
public PushValue(T value, Stack<T> stack)
{
this.stack = stack;
stack.Push(value);
}
#region IDisposable Members
// By using a disposable struct we avoid the overhead of allocating and freeing an instance of a finalizable class.
public void Dispose()
{
if (stack != null)
stack.Pop();
}
#endregion
}
public static T PeekOrDefault<T>(this Stack<T> stack)
{
if (stack == null)
throw new ArgumentNullException();
if (stack.Count == 0)
return default(T);
return stack.Peek();
}
public static PushValue<T> PushUsing<T>(this Stack<T> stack, T value)
{
if (stack == null)
throw new ArgumentNullException();
return new PushValue<T>(value, stack);
}
}
在你的情况 TBaseType
是 Inua.WebApi.Authentication.IUser
。
小提琴。
这篇关于之前修改JSON的通用方法的返回给客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!