我有一个非常大的类库,包含> 100个POCO对象。我需要将这些对象序列化为XML以传输到REST服务。
我一直在尝试使用DataContractSerializer
,但是对于任何null属性,它都会为i:nil="true"
输出XML元素。这会使我传输XML的REST服务运行起来。是的,我意识到它不应该。服务提供商告诉我,纠正这个问题需要几个月的时间。我没有几个月的时间等待这项服务的发挥。
我一直在挖掘文档,试图找到一种方法来抑制这些nil对象的传输。我知道我可以在每个POCO对象的每个属性上将EmitDefaultValue property设置为false。除非我别无选择,否则我不会为100多件物品做到这一点。此外,我不相信我应该被迫使用DataContract属性来注释我的类库对象。我也不想用DataContractSurrogates镜像我的类库。这只是淫秽。
当然,有一个配置选项,我可以指定序列化的默认行为应该是EmitDefaultValue = false
。我虽然找不到它。我希望其他人找到它,或者找到另一个全局选项来抑制XML中的null属性。
DataContractSerializer
实例上设置吗?如果这不存在,那似乎是微软的一次巨大疏忽。
答案 0 :(得分:4)
我认为没有官方方法可以全局设置此属性,可能因为在大多数情况下它被描述为not recommended practice。
但是有解决方法。您可以在DataMemberAttribute
命名空间中定义自己的System.Runtime.Serialization
,默认情况下EmitDefaultValue
设置为false
。把它放在项目的某个地方。这就是你要做的一切。编译器会给你一个警告,说你的类型与导入的类型冲突,但毕竟会使用你的类型。我从Microsoft sources获取此类,将EmitDefaultValue
设置为false
并替换异常抛出,因为它使用的是内部实用程序类:
namespace System.Runtime.Serialization
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class DataMemberAttribute : Attribute
{
string name;
bool isNameSetExplicitly;
int order = -1;
bool isRequired;
bool emitDefaultValue = false;
public string Name
{
get { return name; }
set { name = value; isNameSetExplicitly = true; }
}
public bool IsNameSetExplicitly
{
get { return isNameSetExplicitly; }
}
public int Order
{
get { return order; }
set
{
if (order < 0)
throw new InvalidDataContractException();
order = value;
}
}
public bool IsRequired
{
get { return isRequired; }
set { isRequired = value; }
}
public bool EmitDefaultValue
{
get { return emitDefaultValue; }
set { emitDefaultValue = value; }
}
}
}
现在我们采取new Foo()
:
using System.Runtime.Serialization;
namespace FooBar
{
[DataContract]
public class Foo
{
// Warning about type conflict.
[DataMember]
public string Bar { get; set; }
}
}
它将被DataContractSerializer
序列化为:
<Foo xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>