扩展WebService Proxy类(从WSDL导入)方法

时间:2014-01-04 23:00:45

标签: c# .net webservices-client

我已经基于WSDL(在我的Visual Studio 2010 .NET解决方案中)创建了一个WebService代理类。

现在我需要的是,我对远程Web服务的请求的soap标头有一个特定的格式,想象一下有两个或三个字段并不是很相关。

所以我的解决方案是,我编辑了Visual Studio生成的代码,并注释了我需要自定义soap标头的方法。

接下来,因为web服务类被标记为partial,所以我在一个类中创建了安全代码(生成器无法触及),该类与生成的代码具有相同的名称(因此它是同一个类)并在那里声明方法以前评论过。

我这样声明:

//this is the generated code file
public partial class Invoices: InvoicesWS.invoices
{ 
    //[System.Web.Services.Protocols.SoapDocumentMethodAttribute( ...
    //public RegisterInvoiceResponseType RegisterInvoice(RegisterInvoiceType ...) 
    //{ ... }  
}

//this is the class I created else where in my project
public partial class Invoices: InvoicesWS.invoices
{
    public SecureSoapHeader Security { get; set; }

    [SoapHeader("Security", Direction = SoapHeaderDirection.In)]          
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute(
         "http://someurl.pt/invoices/RegisterInvoice", 
         Use = System.Web.Services.Description.SoapBindingUse.Literal, 
         ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare),
         TraceExtension()]
    public RegisterInvoiceResponseType RegisterInvoice(RegisterInvoiceType RegisterInvoiceElem) 
    {
        object[] results = 
            this.Invoke("RegisterInvoice", new object[] {RegisterInvoiceElem});

        return ((RegisterInvoiceResponseType)(results[0]));
    }
}

因此,为了使我的代理类发送自定义标头,我做了这个。 但每次我记得更新Web引用时,我都必须手动注释掉Visual Studio工具生成的上述方法,以避免由于必须使用方法而导致的冲突 具有相同的签名。

有没有更好的方法或最佳做法来解决这种情况?

请不要建议我用WCF做,我知道解决方案, 但正确的是这是一直在工作并改变它的代码 这次不是可能的。

感谢。

1 个答案:

答案 0 :(得分:1)

您可以使用SoapExtension来实现它。您可以创建实现SoapExtension的类,并在web.config中注册它。

肥皂扩展样本:

public class SecureSoapExtension : SoapExtension
{

    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return null;
    }

    public override object GetInitializer(Type serviceType)
    {
        return null;
    }

    public override void Initialize(object initializer)
    {

    }

    public override void ProcessMessage(SoapMessage message)
    {
        // just for out requests
        if (message.Stage == SoapMessageStage.BeforeSerialize)
        {
            // add needed soap header here
            message.Headers.Add(new SecureSoapHeader());
        }
    }
}

在web.config中注册以应用于所有Web服务:

  <system.web>
      <webServices>
          <soapExtensionTypes>
              <add type="MyTestMvcApplication.SecureSoapExtension, MyTestMvcApplication, Version=1.0.0.0, Culture=neutral"></add>
          </soapExtensionTypes>
      </webServices>
  </system.web>

重要说明:如果您从外部项目调用Web服务,假设您有一个类库,您可以在其中编写所有代理处理逻辑。您必须将此项添加到您的调用项目web.config / app.config中,否则它将无效:

  <system.web>
      <webServices>
          <soapExtensionTypes>
              <add type="MyTestMvcApplication.SecureSoapExtension, MyTestMvcApplication, Version=1.0.0.0, Culture=neutral"></add>
          </soapExtensionTypes>
      </webServices>
  </system.web>

什么样的理由,因为它是一个Web服务扩展,它让你“代理的最终调用者”,决定是否扩展web服务请求。