有没有办法让JavaScriptSerializer忽略某种泛型类型的属性?

Mr *_*ell 0 c# json entity-framework

我正在为我的模型使用实体框架,我需要将它们序列化为JSON.问题是EF包含了所有这些非常好的导航集合(例如我的用户模型上有一个Orders属性),当我去序列化这些对象时,序列化程序试图获取这些集合的值,EF对我大喊大叫使用处置的上下文

ObjectContext实例已被释放,不能再用于需要连接的操作.

我知道我可以使用[ScriptIgnore]来装饰我的属性,以使序列化器不管它们,但这就是EF的一个问题,因为它为这些属性生成了代码.

有没有办法使序列化程序不序列化通用类型EntityCollection <>的属性?

或者有没有办法用另一个像JSON.Net这样强大的json库来做到这一点?

drz*_*aus 8

您可以声明自定义合约解析程序,该解析程序指示要忽略的属性.根据我在这里找到的答案,这是一个通用的"可忽略的" :

/// <summary>
/// Special JsonConvert resolver that allows you to ignore properties.  See https://stackoverflow.com/a/13588192/1037948
/// </summary>
public class IgnorableSerializerContractResolver : DefaultContractResolver {
    protected readonly Dictionary<Type, HashSet<string>> Ignores;

    public IgnorableSerializerContractResolver() {
        this.Ignores = new Dictionary<Type, HashSet<string>>();
    }

    /// <summary>
    /// Explicitly ignore the given property(s) for the given type
    /// </summary>
    /// <param name="type"></param>
    /// <param name="propertyName">one or more properties to ignore.  Leave empty to ignore the type entirely.</param>
    public void Ignore(Type type, params string[] propertyName) {
        // start bucket if DNE
        if (!this.Ignores.ContainsKey(type)) this.Ignores[type] = new HashSet<string>();

        foreach (var prop in propertyName) {
            this.Ignores[type].Add(prop);
        }
    }

    /// <summary>
    /// Is the given property for the given type ignored?
    /// </summary>
    /// <param name="type"></param>
    /// <param name="propertyName"></param>
    /// <returns></returns>
    public bool IsIgnored(Type type, string propertyName) {
        if (!this.Ignores.ContainsKey(type)) return false;

        // if no properties provided, ignore the type entirely
        if (this.Ignores[type].Count == 0) return true;

        return this.Ignores[type].Contains(propertyName);
    }

    /// <summary>
    /// The decision logic goes here
    /// </summary>
    /// <param name="member"></param>
    /// <param name="memberSerialization"></param>
    /// <returns></returns>
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        if (this.IsIgnored(property.DeclaringType, property.PropertyName)) {
            property.ShouldSerialize = instance => { return false; };
        }

        return property;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

var jsonResolver = new IgnorableSerializerContractResolver();
// ignore single property
jsonResolver.Ignore(typeof(Company), "WebSites");
// ignore single datatype
jsonResolver.Ignore(typeof(System.Data.Objects.DataClasses.EntityObject));
var jsonSettings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, ContractResolver = jsonResolver };
Run Code Online (Sandbox Code Playgroud)