如何设置soap消息的属性:
例如我的肥皂混乱看起来像下面的
<doPaymentResult xmlns:a="http://schemas.datacontract.org/2004/07/MemoService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:errors i:nil="true"/>
<a:messages>
<a:MessageEntity>
<a:codeField>Payment Request Successful</a:codeField>
<a:textField i:nil="true" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
</a:MessageEntity>
</a:messages>
<a:requestTrackCode>20130430T125904R14646</a:requestTrackCode>
<a:status i:nil="true"/>
</doPaymentResult>
</doPaymentResponse>
但我需要一条肥皂信息,它取的属性不是元素 喜欢以下
<doPaymentResult xmlns:a="http://schemas.datacontract.org/2004/07/MemoService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:errors i:nil="true"/>
<a:messages>
<a:MessageEntity codeField="Payment Request Successful">
some text here
</a:MessageEntity>
</a:messages>
<a:requestTrackCode>20130430T125904R14646</a:requestTrackCode>
<a:status i:nil="true"/>
</doPaymentResult>
</doPaymentResponse>
我在课堂上使用datacontract。
答案 0 :(得分:4)
这是一个常见问题 - 您希望将对象从WCF服务返回为XML,但您希望或者需要将部分或全部属性值作为XML属性而不是XML元素提供;但你不能,因为DataContractSerializer不支持属性(如果你进行了网络搜索,你很可能已经看过这个StackOverflow QA)。您很可能已将所有WCF服务代码迁移到使用XmlSerializer(包含所有XmlElement / XmlAttribute / XmlType属性等) - 并且您已大声诅咒。
好吧,我来这里是为了拯救你,因为它是可能的 - 问题的答案实际上是从MSDN文章“数据合同序列化程序支持的类型”中推断出来的。
我要给出的例子纯粹仅用于说明目的。我没有很多时间,所以和我一起工作吧! •创建一个新的Asp.Net WCF服务应用程序,您可以使用Cassini作为您的Web服务器(可能更容易 - 否则您可能必须启用Asp.Net兼容模式)。 •打开web.config并删除为新服务创建的元素。 •此示例的界面和实现模型过度。将[ServiceContract]和[OperationContract]声明从为新服务创建的接口移动到也创建的类。删除界面。 •打开.svc标记文件并在末尾添加以下内容:Factory =“System.ServiceModel.Activation.WebServiceHostFactory” - 这将为此服务启用零配置WCF模型(我们将创建RESTful服务)。 •将以下类声明粘贴到您的svc代码隐藏中:
public interface IExampleData
{
string Description { get; set; }
string Name { get; set; }
int ID { get; set; }
}
public class ExampleData : IExampleData
{
public string Description { get; set; }
public string Name { get; set; }
public int ID { get; set; }
}
public class ExampleDataAttributed : ExampleData, IXmlSerializable
{
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
//implement if remote callers are going to pass your object in
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteAttributeString("id", ID.ToString());
writer.WriteAttributeString("name", Name);
//we'll keep the description as an element as it could be long.
writer.WriteElementString("description", Description);
}
#endregion
}
Just to demonstrate the point, the class that will be part-serialized to attributes simply derives from one that will be serialized as normal.
•Now add the following two methods to your service class:
[OperationContract]
[WebGet(UriTemplate = "/test1")]
public ExampleData Test1()
{
return new ExampleData() { ID = 1,
Name = "Element-centric",
Description =
"The contents of this item are entirely serialized to elements - as normal" };
}
[OperationContract]
[WebGet(UriTemplate = "/test2")]
public ExampleDataAttributed Test2()
{
return new ExampleData_Attributed() { ID = 2,
Name = "Mixed",
Description =
"Everything except this description will be serialized to attributes" };
}
盖上盖子,烘烤40分钟(即 - 构建它)。
如果您将服务保留为Service1.svc,则运行它并打开IE并浏览到http:// localhost:[cassini端口] / test1
结果应如下所示:
<JSLabs.ExampleData
xmlns="http://schemas.datacontract.org/2004/07/ExampleNamespace"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Description>
The contents of this item are entirely serialized to elements - as normal
</Description>
<ID>
1
</ID>
<Name>
Element-centric
</Name>
</JSLabs.ExampleData>
现在浏览到http:// localhost:[cassini端口] / test2
<JSLabs.ExampleDataAttributed id="2" name="Mixed"
xmlns="http://schemas.datacontract.org/2004/07/JobServe.Labs.Web">
<description>Everything except this description will be
serialized to attributes</description>
</JSLabs.ExampleDataAttributed>
WCF数据合同序列化程序自动放入类型的那个令人讨厌的“可怕的”xmlns =“属性使得它变得不那么令人印象深刻 - 但是,正如您所看到的,'ID'和'Name'属性确实已经被推出属性!
我们可以让两个方法返回IExampleData,然后在该接口上使用KnownType属性以使其支持(根据返回的方法代码)。
为了支持从属性反序列化对象,您所要做的就是实现IXmlSerializable.ReadXml方法。
最后,正如前面提到的MSDN文章所述的支持类型 - 您还应该能够使用XmlElement / XmlNode类型作为直接表示XML的方式 - 像这种情况一样,DataContractSerializer采用短路径并简单地获取Xml。
如果您为XML或JSON客户端双输出对象,这也不应影响JSON格式。