实际上这个问题继续我的previous question关于SOAP消息序列化并不允许通过XmlRoot更改根名称,因此我通过WCF消息手动更改消息的根名称检查员(通过IClientMessageInspector),这是我遇到的新问题。
[ServiceContract]
public interface ICustomerService
{
[OperationContract]
bool EvaluateCustomer(Customer customer);
}
public class CustomerService : ICustomerService
{
public bool EvaluateCustomer(Customer customer)
{
// Evaluation is here ...
}
}
public class Customer
{
public Customer() { }
public Customer(string id, string name, int age)
{
ID = id;
Name = name;
Age = age;
}
public string ID { get; set; }
public String Name { get; set; }
public int Age { get; set; }
}
并实现客户端消息检查器以修改消息。请注意,问题是由更改消息标记引起的:
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
MemoryStream ms = new MemoryStream();
XmlWriter xw = XmlWriter.Create(ms);
request.WriteMessage(xw);
xw.Flush();
ms.Position = 0;
string body = Encoding.UTF8.GetString(ms.ToArray());
xw.Close();
// There will be no problem if no change with the tag
body = body.Replace("<customer", "<MyCustomer");
body = body.Replace("</customer>", "</MyCustomer>");
ms = new MemoryStream(Encoding.UTF8.GetBytes(body));
XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(ms, new XmlDictionaryReaderQuotas());
Message newMessage = Message.CreateMessage(xdr, int.MaxValue, request.Version);
newMessage.Properties.CopyProperties(request.Properties);
request = newMessage;
return null;
}
在此之前一切正常,传入的请求消息如下:
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://tempuri.org/ITestService/EvaluateCustomer</a:Action>
<a:MessageID>urn:uuid:b35ab229-129a-469b-9a54-be3eaae53e3a</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
</s:Header>
<s:Body>
<EvaluateCustomer xmlns="http://tempuri.org/">
<customer xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfTest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<d4p1:Age>43</d4p1:Age>
<d4p1:ID>No2</d4p1:ID>
<d4p1:Name>Jones</d4p1:Name>
</customer>
</EvaluateCustomer>
</s:Body>
</s:Envelope>
我需要的是更改<customer>
标签,这就是BeforeSendRequest所做的。但是当我在服务操作EvaluateCustomer中断调用时,我发现参数customer是null而不是新的客户实例,为什么?我用IXmlSerializable实现了Customer类,发现如果在SOAP消息中更改了类根标记,则不会调用ReadXml,为什么?以及如何实现方案以便可以调用ReadXml或新的传入服务参数(上例中的客户)将不再为空?
我使用ServiceHost和WSHttpBinding测试了上述问题,使用ChannelFactory创建了wcf客户端,并使用Endpoint行为扩展了消息检查器。
欢迎并赞赏任何提示。
答案 0 :(得分:0)
我相信你需要先装饰顾客&#39;具有[DataContract]属性的类。设置&#39;名称&#39;属于&#39; MyCustomer&#39;。
的部分属性还要记住将[DataMember]添加到要序列化的成员中。