为什么我得到空参数在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创建的,消息检查器扩展了端点行为。

为什么我得到空参数在wcf服务调用,如果我改变消息标签名称

我认为您需要首先用[DataContract]属性装饰'Customer'类。设置该属性的'Name'部分为'MyCustomer'。