为什么我得到空参数在wcf服务调用,如果我改变消息标签名称
本文关键字:如果 改变 标签名 调用 消息 wcf 参数 为什么 服务 | 更新日期: 2023-09-27 18:19:04
实际上,这个问题继续与我之前的问题有关,这是关于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>
标签,这就是beforeendrequest所做的。但是,当我在服务操作EvaluateCustomer中中断调用时,我发现参数customer为空,而不是一个新的customer实例,这是为什么呢?我曾经用IXmlSerializable实现过Customer类,并且发现如果在SOAP消息中更改了类根标记,则不会调用ReadXml,这是为什么呢?以及如何实现该场景,以便能够调用ReadXml或传入的新服务参数(在上面的示例中为customer)不再为空?
我用ServiceHost和WSHttpBinding测试了上面的问题,wcf客户端是用ChannelFactory创建的,消息检查器扩展了端点行为。
我认为您需要首先用[DataContract]属性装饰'Customer'类。设置该属性的'Name'部分为'MyCustomer'。