在Custom MediaType Formatter中使用序列化时出错

时间:2017-07-17 16:13:31

标签: model-view-controller json.net mediatypeformatter

我使用每个请求逻辑

实现了自定义媒体类型格式化程序
public class JsonPermissionBasedFormatter : PartialJsonMediaTypeFormatter
    {
        public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
        {
            User user = request.GetOwinContext()?.Request.Get<User>("AuthorizationFilter:CurrentUser");
            var formatter = (PartialJsonMediaTypeFormatter)base.GetPerRequestFormatterInstance(type, request, mediaType);
             formatter.SerializerSettings = SerializerSettings;
            formatter.SerializerSettings.ContractResolver = new PermissionBasedContractResolver(user);
            return formatter;
        }
    }

public class PermissionBasedContractResolver:DefaultContractResolver     {         private readonly User _user;

    public PermissionBasedContractResolver(User user)
    {
        _user = user;
        NamingStrategy = new CamelCaseNamingStrategy
        {
            ProcessDictionaryKeys = true,
            OverrideSpecifiedNames = true
        };
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        if (member == null)
        {
            throw new ArgumentNullException(nameof(member));
        }
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        var propertyInfo = member as PropertyInfo;
        if (propertyInfo != null)
        {
            if (!PermissionsHelper.IsPropertyVisibleForUser(propertyInfo, _user))
            {
                property.ShouldSerialize = DoNotSerialize;
            }
        }
        return property;
    }

    static bool DoNotSerialize(object o)
    {
        return false;
    }
}
public static bool IsPropertyVisibleForUser(PropertyInfo info, User user)
    {
        if (info.GetCustomAttribute<IgnoreDataMemberAttribute>() != null) 
return false;
        if (user == null) return true;
        var permissionForExportAttribute = 
info.GetCustomAttribute<VisibleForAttribute>();
        if (permissionForExportAttribute != null)
        {
            return 
user.HasPermission(permissionForExportAttribute.Permission);
        }
        return true;
    }

PermissionBasedContractResolver为序列化添加依赖于用户权限的自定义逻辑。例如,具有管理员权限的用户在json中接收其他属性,而普通用户则没有。 但是如果以下列方式运行请求:

Parallel.For(1, 10000, _ =>
            {
                Get(ordinaryUser, isAdmin: false);
                Get(adminUser, isAdmin: true);
            });

偶尔会获得普通的用户json属性,仅适用于管理员。我不明白它是如何发生的。 问题只能在一些负载下重现,如果通过邮递员手动运行请求 - 一切正常。你能说出它是什么,或者提出如何调查这个问题的建议。

0 个答案:

没有答案