【问题标题】:Extending WebService Proxy class (imported from WSDL) methods扩展 WebService 代理类(从 WSDL 导入)方法
【发布时间】:2014-01-06 19:27:42
【问题描述】:

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

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

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

接下来,因为 web 服务类被标记为部分,我在一个与生成的类同名的类中创建了安全代码(生成器不能触及)(所以它是同一个类)并在那里声明方法之前注释掉了。

我是这样声明的:

//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]));
    }
}

所以,为了让我的代理类发送一个自定义标头,我这样做了。 但是每次我记得更新网络参考时,我都必须手动注释掉上面由 Visual Studio 工具生成的方法,以避免由于必须方法而引起的冲突 签名相同。

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

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

谢谢。

【问题讨论】:

  • 如何将您的方法重命名为 ex,RegisterInvoice2 并在您的代码中使用它而不是 RegisterInvoice
  • 感谢 L.B 的建议,但这似乎是一种解决方法,我想尽可能直截了当。还是谢谢。

标签: c# .net webservices-client


【解决方案1】:

您可以通过SoapExtension 实现它。您可以创建实现 SoapExtension 的类,并将其注册到 web.config 中。

soap 扩展示例:

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 服务请求。

【讨论】:

  • 我喜欢你的解决方案,会试一试。以后我会告诉你它是否有效。谢谢。
  • 我已更新您的答案,将其标记为答案。我做了一点评论,让您的解决方案适用于所有情况。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
  • 2014-11-08
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多