尝试使用重载的Equals(object obj)
方法序列化自定义类型的集合。我正在使用Newtonsoft.Json.JsonConvert.SerializeObject(object value)
来实现这一目标。
这是我的抽象基本视图模型,有问题的视图模型从该模型继承:
public abstract class BaseCollectibleViewModel
{
protected abstract bool CompareParameters(object item);
protected abstract List<int> GetParameters();
public override bool Equals(object obj)
{
if (CompareParameters(obj))
{
return true;
}
return false;
}
public override int GetHashCode()
{
int hash = 13;
foreach (var parameter in GetParameters())
{
hash = (hash * 7) + parameter.GetHashCode();
}
return hash;
}
public static bool operator ==(BaseCollectibleViewModel a, BaseCollectibleViewModel b)
{
if (a.Equals(b))
{
return true;
}
return false;
}
public static bool operator !=(BaseCollectibleViewModel a, BaseCollectibleViewModel b)
{
if (a.Equals(b))
{
return false;
}
return true;
}
}
这是实际的视图模型:
public class ImagesViewModel : BaseCollectibleViewModel, ISourceImage
{
public string Name { get; private set; }
public string Type { get; private set; }
[ScriptIgnore]
public Stream Content { get; private set; }
[ScriptIgnore]
private HttpPostedFileBase _file;
[ScriptIgnore]
public HttpPostedFileBase File
{
get
{
return _file;
}
set
{
_file = value;
Name = File.FileName;
Type = File.ContentType;
Content = new MemoryStream();
File.InputStream.CopyTo(Content);
}
}
protected override bool CompareParameters(object obj)
{
var temp = obj as ImagesViewModel;
if(temp == null)
{
return false;
}
return
(Name == temp.Name &&
Type == temp.Type);
}
protected override List<int> GetParameters()
{
return new List<int>()
{
Name.GetHashCode(),
Type.GetHashCode()
};
}
}
请注意ScriptIgnore
属性。我甚至在私人领域有一个。该程序在基类的==
运算符上中断,因为传递的两个参数都为null。
这是序列化代码:
[HttpPost]
public string GetSessionImages()
{
var imagesInSession = _imagesSessionService.GetCollection();
return JsonConvert.SerializeObject(imagesInSession, Formatting.Indented);
}
屏幕截图显示了继承视图模型上抽象CompareParameters(object obj)
方法的实现。该流是Content
属性流,我已经检查过了。为什么会这样?
编辑:当没有覆盖等于时,我得到一个JsonSerializationException
陈述:
{“从'ReadTimeout'获取值时出错 'System.IO.MemoryStream'。“}
编辑2:根据dbc的评论我已将[ScriptIgnore]
替换为[JsonIgnore]
,并且代码在一定程度上起作用。
但是,我必须注释掉运算符实现,因为'=='运算符将作为null
参数传递BaseCollectibleViewModel b
值。
答案 0 :(得分:1)
由于您使用的是json.net,因此您必须使用[JsonIgnore]
将成员标记为忽略:
using Newtonsoft.Json;
public class ImagesViewModel : BaseCollectibleViewModel, ISourceImage
{
public string Name { get; private set; }
public string Type { get; private set; }
[ScriptIgnore]
[JsonIgnore]
public Stream Content { get; private set; }
[ScriptIgnore]
[JsonIgnore]
public HttpPostedFileBase File { get { ... } set { ... } }
没有必要使用[JsonIgnore]
标记完全私有成员,因为Json.NET默认不对这些成员进行序列化。
或者,如果您不希望模型依赖于Json.NET,则可以使用conditional property serialization无条件地禁止使用相同的成员:
public class ImagesViewModel : BaseCollectibleViewModel, ISourceImage
{
public string Name { get; private set; }
public string Type { get; private set; }
[ScriptIgnore]
public Stream Content { get; private set; }
public bool ShouldSerializeContent() { return false; }
[ScriptIgnore]
public HttpPostedFileBase File { get { ... } set { ... } }
public bool ShouldSerializeFile() { return false; }
请注意,其他序列化程序(包括XmlSerializer
)也会尊重ShouldSerializeXXX()
条件序列化模式,如 ShouldSerialize*() vs *Specified Conditional Serialization Pattern 中所述 - 副作用可能是是否合意。
(顺便提一下,您可能需要检查一下,如 JSON.NET Parser *seems* to be double serializing my objects 所示,您没有对数据进行双重序列化。)