我正在使用JSON.NET,并且在WEBAPI对象反序列化过程中遇到了一些麻烦。经过一些研究后,我发现该课程标有[Serializable]。当我删除它时,反序列化就好了。
有关这方面的更多详细信息,请访问:
Why won't Web API deserialize this but JSON.Net will?
现在谈到我使用binaryformatter创建从此对象类计算的哈希值的问题。 但Binaryformatter要求必须将类标记为[Serializable]。
你能否建议我采用任何方法让两件事同时发挥作用?
答案 0 :(得分:24)
找到解决方案:
首先,检查您的Newtonsoft.JSON版本是否大于4.5或只是使用NuGET进行更新
根据版本说明,两者都可以使用一些额外的注释从这个版本开始协同工作。
“现在,如果您正在序列化具有该属性但不想要新行为的类型,则可以使用JsonObjectAttribute在类型上覆盖它”
[JsonObject]
[Serializable]
public class Foobar {
现在可以使用JSON.NET,在我的例子中,可以使用带有[Serializable]属性的binaryformatter。
答案 1 :(得分:5)
在每个类上指定JsonObject的替代方法是告诉web.api全局忽略Serialize属性。这可以通过重置web api JsonFormatter上的DefaultContractResolver来完成:
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver();
(使用NewtonSoft.Json.Serialization,其中config是System.Web.Http.HttpConfiguration)
从NewtonSoft v4.5开始,DefaultContractResolver上的IgnoreSerializableAttribute属性设置为true,但默认情况下,围绕DefaultContractResolver的web api包装器将此设置为false。
答案 2 :(得分:0)
我正在使用具有Serializable属性的POCO。在第一种情况下,使用以下方法将请求发布到WebApi可以起作用:
JsonMediaTypeFormatter f = new JsonMediaTypeFormatter()
{
SerializerSettings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = true
}
}
};
var result = client.PostAsJsonAsync<IEnumerable<Company>>("company/savecompanies", companies).Result;
//I have truncated the below class for demo purpose
[Serializable]
public class Company
{
public string CompanyName {get;set;}
}
但是,当我尝试读取WebApi的响应时(该对象以JSON回发),该对象未正确反序列化。没有错误,但是属性值为null。以下代码不起作用:
var readObject = result.Content.ReadAsAsync<IEnumerable<Company>>().Result;
我阅读了Newtonsoft.Json网站https://www.newtonsoft.com/json/help/html/SerializationAttributes.htm上给出的文档,发现了以下内容,并引用了该网站的内容:
Json.NET属性优先于标准.NET序列化 属性(例如,是否同时具有JsonPropertyAttribute和DataMemberAttribute 存在于一个属性上,并且都自定义名称,该名称来自 将使用JsonPropertyAttribute)。
因此,很清楚在标准.NET属性之前是否存在Newtonsoft.Json属性,它们将具有优先权。因此,我可以将同一类用于两个目的。一,当我想发布到WebApi时,Newtonsoft Json序列化器将启动;二,当我想使用BinaryFormatter.Serialize()方法std .NET Serializable属性时,将起作用。
@Javier给出的答案也证实了这一点。 所以我将公司类别修改为:
[JsonObject]
[Serializable]
public class Company
{
public string CompanyName {get;set;}
}
我能够将相同的类用于这两个目的。而且不需要以下代码:
JsonMediaTypeFormatter f = new JsonMediaTypeFormatter()
{
SerializerSettings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = true
}
}
};