哦,伟大的StackOverflow之神,请听我一声叹息:
我正在编写.NET 4.5库代码与Oracle SalesCloud服务通信,并且在处理C#对象上值为null字符串的SOAP请求时遇到了问题。
属性的XSD规范如下:
<xsd:element minOccurs="0" name="OneOfTheStringProperties" nillable="true" type="xsd:string" />
在VS2013中使用“添加服务引用...”工具并编写请求更新除OneOfTheStringProperties以外的其他内容时,输出结果如下:
<OneOfTheStringProperties xsi:nil="true></OneOfTheStringProperties>
在服务器端,这会引起两个问题。首先,由于只读属性也是以这种方式指定的,因此服务器拒绝整个请求。其次,这意味着我可能会无意中清除我想要保留的值(除非我每次都发送每个属性...效率低下且编码麻烦)。
我在谷歌上搜索了很久,但并没有找到最好的解决方法,我不想深入编写自定义XmlSerializer(以及所有相关的测试/边缘情况),除非这是最佳选择。
到目前为止,我能找到的最好方法是遵循[Property]Specified模式。因此,对于每个可用的字符串属性,我必须将以下内容添加到Reference.cs中的定义中。
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool OneOfTheStringPropertiesSpecified
{
get { return !String.IsNullOrEmpty(OneOfTheStringProperties); }
set { }
}
这需要打很多字,但它有效,并且SOAP消息的日志跟踪是正确的。
我希望得到以下三种方法之一的建议:
A config switch, specific XmlSerializer override, or some other fix that will suppress the .NET 4.5 XmlSerializer output for null strings
Something like the same secret formula that will put out "proper" XML such as
<OneOfTheStringProperties xsi:nil="true" />
A targeted tutorial to create an extension (or an existing VS2013 extension) that will allow me to right-click on a string property and insert the the following pattern:
[System.Xml.Serialization.XmlIgnoreAttribute()] public bool [$StringProperty]Specified { get { return !String.isNullOrEmpty([$StringProperty]); } set { } }
我也愿意接受任何其他建议。如果只是需要使用正确的搜索术语(显然我不知道),那将非常感激。
为了实现这个请求,作为知识守护者,我献上这只牺牲羊。
为了澄清
我并不是在寻找一键式魔法。作为一名开发人员,尤其是在一个由于需求而经常更改底层结构的团队中工作的人,我知道保持事物运行需要很多工作。
但是,我所寻找的是在每次刷新结构时减少工作量的合理方法(对于其他人来说,是实现相同目标的简化方案)。例如,使用*Specified表示在给定示例中输入大约165个字符。对于具有45个字符串字段的合同,这意味着每次模型更改时我都要输入超过7,425个字符 - 这只是一个服务对象!共有大约10-20个可用的服务对象。
右键单击的想法将把它缩减到45个右键单击操作...更好。
将自定义属性放在类上会更好,因为每次刷新只需要做一次。
理想情况下,app.config中的运行时设置将是一劳永逸的--第一次实现可能有多难,因为它进入了库。
我认为真正的答案比每个类中的近7500个字符要好得多,可能不如一个简单的app.config设置那么好,但这些方案肯定存在或者可以被制作出来。
[XmlElement(IsNullable=true)]
应用于一堆字符串属性,您想以编程方式忽略此属性,而不是手动从生成的代码中删除它? - dbc