代码之家  ›  专栏  ›  技术社区  ›  carson

有没有更好的方法在C中定制SOAP头#

  •  1
  • carson  · 技术社区  · 16 年前

    在过去,我需要在使用导入的WSDL web引用的C#项目中创建自定义SOAP头。我找到了一种方法来做,但我从来都不满意,我有感觉想知道是否有更好的方法。我所做的是创建一个从SoapHeader派生的头:

    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://model.test.net")]
    [System.Xml.Serialization.XmlRootAttribute("securitytoken", Namespace = "http://model.test.net", IsNullable = false)]
    public class SpecialHeader : SoapHeader
    { 
      [System.Xml.Serialization.XmlTextAttribute()]
      public string aheadervalue;
    }
    

    然后我不得不修改从WSDL生成的代码并添加一个引用 ce到新头的一个实例,在每次web调用之前

    [System.Web.Services.Protocols.SoapHeaderAttribute("instancename", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
    

    其中“instance name”是生成类中自定义头的实例变量名。

    这很好,只是WSDL中的任何更改都需要重新执行,因为它重新生成了类。在其他语言中,可以在生成的代码之外添加头,所以我可能缺少在C#中的方法。有更好的方法吗?

    4 回复  |  直到 12 年前
        1
  •  3
  •   khebbie    16 年前

    似乎您正在使用.Net 2.0和asmx webservices。 你知道在.Net 3.0中有一个叫做WCF(Windows通信框架)的框架吗。 我知道迁移到一个新的框架并不容易,但是有了WCF,你会得到很多。 也就是说,操作soap头是使用MessageContracts完成的。

        2
  •  2
  •   vardars    13 年前

    因为生成类的焦点是一个部分类。您可以在另一个具有相同名称空间和类名的文件(同样是部分类)上定义它。然后可以重写其虚拟方法并定义一次。

    在新的类文件上,您可以使用“getwriteformessage”重写并向其添加新的SOAP头。

    public partial class SampleService
    {
        public string MessageID { get; set; }
    
        protected override System.Xml.XmlWriter GetWriterForMessage(System.Web.Services.Protocols.SoapClientMessage message, int bufferSize)
        {
            message.Headers.Add(new UsernameSoapHeader("Username"));
            message.Headers.Add(new PasswordSoapHeader("Password"));
            message.Headers.Add(new MessageIDSoapHeader(MessageID));
            return base.GetWriterForMessage(message, bufferSize);
        }
    }
    
        3
  •  1
  •   Eric Rosenberger    16 年前

    由于生成器生成部分类,您可以:

    1. 向项目中添加一个文件,该文件使用另一个“部分”部分扩展web服务类(从SoapHttpClientProtocol派生的类)(即,使用与生成的类相同的名称空间和名称,并将其标记为“部分”)。

    2. 稍微重命名这些方法,使它们与生成代码中的方法不冲突,并更改传递给Invoke的名称以匹配。(您可能还必须调整方法上的其他属性,以确保它们仍然映射到WSDL中的正确调用。)

    3. 将自定义头属性添加到重命名的方法,并将头实例字段添加到扩展部分。

    4. 从代码中调用重命名的版本,而不是原始版本。

    它仍然不理想,但是没有尝试截取原始的XML消息并直接将头放入(您可能会这样做,但这会很糟糕),没有我知道的任何其他选项(无论如何都不转移到WCF)。

        4
  •  0
  •   Hasani Blackwell    14 年前

    GetWriterForMessage 方法确保我的标题始终存在。我会在每次调用该方法时更新头值。